题目1:
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
思路:
题目只要求输出最大的和,未要求输出令和最大的序列数,因此,最简单的方法是直接将数字累加,保存每次得到的最大值(若序列前几个数为负数,后面为正数,直接从正数开始累加的值当然是最大的)。
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
if((int)array.size()==0)
return 0;
//ans的初值不设为0的原因是:考虑到有可能数组中所有数字均为负数的情况
int sum=0,ans=array[0];
for(int i=0;i<(int)array.size();i++){
sum<=0?sum=array[i]:sum+=array[i];
if(ans<sum)
ans=sum;
}
return ans;
}
};
题目2:
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
思路:
举个例子就清楚了。三个数分别为205、215、225,
个位上1的数有:20*1+1; 21*1+1; 22*1+1
十位上1的数有:2*10+0; 2*10+6; 2*10+10
百位上1的数有:0+100; 0+100; 0+100
可以看到,若当前位数的值为0,后面加的数为0;若当前位数的值为1,后面加的数为:比当前位数低一位的数的值+1;若当前位数的值大于1,后面加的数为当前位数(个位为1,十位为10,百位为100)。
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
int ans=0;
for(int wei=1,high=n/10,cur=n%10,low=0;n/wei;){
ans+=high*wei+(cur==0?0:cur==1?low+1:wei);
wei*=10; //位数左移
high=n/wei/10; //比当前位数高的位数的值
cur=n/wei%10; //当前位数的值
low=n%wei; //比当前位数低一位的值
}
return ans;
}
};