剑指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; }