剑指offer(30)连续子数组和的最大值

题目描述

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度至少是1)

 

题目分析

这题我们可以分析数组,一个一个的找规律。不过如果知道动态规划的话,很容易发现后面的结果跟前面的有关系。如果用函数sum(i)表示以第i个数字结尾的子数组的最大和,那么我们只需要求出

max[sum(i)],其中可以用如下递归公式。

当i=0时,或者sum(i-1)<=0时,sum(i)=array[i];

当i≠0时,或者sum(i-1)>0时,sum(i)=sum(i-1)+array[i];

那么就可以写代码了

 

代码

// 暴力解法
function NumberOf1Between1AndNSolution(n) {
  let ones = 0;
  for (let i = 0; i <= n; i++) {
    let num = i;
    while (num) {
      if (num % 10 === 1) {
        ones++;
      }
      num = ~~(num / 10);
    }
  }
  return ones;
}

// 优化版
function NumberOf1Between1AndNSolution2(n) {
  if (n <= 0) return 0;
  let count = 0;
  for (let i = 1; i <= n; i *= 10) {
    const a = ~~(n / i),
      b = n % i;
    count = count + ~~((a + 8) / 10) * i + (a % 10 === 1) * (b + 1);
  }
  return count;
}

 

posted @ 2018-04-07 04:27  汕大小吴  阅读(1304)  评论(0编辑  收藏  举报