1. 连续子数组的最大和
思路一:从头开始遍历,设置两个数,一个记录当前序列和,一个记录最大序列和。如果当前序列和小于等于0,说明前面的序列没有用,令当前序列和为下一个数字,如果大于0,就继续往上加,再与最大序列和做对比。
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int len=array.size();
if(len<=0) return 0;
int cur=0;
int res=0x80000000;//最小负数
for(int i=0;i<len;i++)
{
if(cur<=0)
cur=array[i];//小于等于0,舍去记录的序列
else
{
cur+=array[i];//否则序列加一个数
}
res=max(res,cur);//比较
}
return res;
}
};思路二:动态规划。当i=0或f(i-1)<=0时,f(i)=pData[i];当i≠0且f(i-1)>0时,f(i)=f(i-1)+pData[i],我们要求的就是max(f[i]) 0<=i<=n;其实动态规划与思路一思想是一样的。
2. 1-n整数中出现1的次数
思路一:暴力,另写一个函数计算每个数字出现1的次数,然后遍历1-n。
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
if(n<1) return 0;
int count=0;
for(int i=1;i<=n;i++)
{
int temp=i;//借助一个temp,直接用i的话i会一直为0
while(temp)
{
if(temp%10==1)
count++;
temp=temp/10;
}
}
return count;
}
};思路二:以21345为例子,将其分为1-1345和1346-21345两个部分。先看1346-21345中出现的次数,分两种情况:第一种情况,计算万位的1,出现了10000次,注意次数如果21345是小于19999的数字,那么就不会出现10000次,而是x-10000+1次;第二种情况,分析1除了最高位之外的其他四位数中的情况,由于最高位是2,我们可以再分为,1346-11345与11345-21345两段。每一段剩下的四位数字中,选择其中一位是1,其余三位可以从0-9这十个数字中任意选择。根据排列组合,次数是2×4×10^3.再看1-1345,递归即可。
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
if(n<=0)
return 0;
char strN[50];
sprintf(strN,"%d",n);//转换成字符串
return NumberOf1(strN);
}
int NumberOf1(const char* strN)
{
if(!strN||*strN<'0'||*strN>'9'||*strN=='\0')
return 0;//结束条件
int first=*strN-'0';//最高位
unsigned int length=static_cast<unsigned int>(strlen(strN));
if(length==1&&first==0)
return 0;
if(length==1&&first>0)
return 1;//0-9
int numFirstDigit=0;//最高位
if(first>1)
numFirstDigit=pow(10,length-1);
else if(first==1)
numFirstDigit=atoi(strN+1)+1;//10000-12345
int numOtherDigits=first*(length-1)*pow(10,length-2);//剩余位数排列组合
int numRecursive=NumberOf1(strN+1);//递归
return numFirstDigit+numOtherDigits+numRecursive;
}
};3.数字序列中某一位的数字
思路:以第1001为为例子,序列前十位是0-9这十个数字,1001>10,从991开始找两位数,两位数一共180,991>180,所以第991位在所有的两位数之后,991-190=881;三位数一共2700位,由于881<2700,所以第881位是某三位数中的一位。由于811=270×3+1,可得811位是100+270这个数的中间一位,也就是7.
int digitAtIndex(int index)
{
if(index==0)
return -1;
int digits=1;
while(true)
{
int numbers=countOfIntegers(digits);//计算m位的数字有多少个
if(index<numbers*digits)
{
return digitAtIndex(index,digits);
}
index-=digits*numbers;//减去前面的位数
digits++;
}
return -1;
}
int countOfIntegers(int digits)//计算m位的数字个数
{
if(digits==1)
return 10;
int count=(int)pow(10,digits-1);
return 9*count;
}
int digitAtIndex(int index,int digits)
{
int number=beginNumber(digits)+index/digits;
int indexFromRight=digits-index%digits;
for(int i=1;i<indexFromRight;i++)
{
number/=10;
}
return number%10;
}
int beginNumber(int digits)
{
if(digits==1)
return 0;
return (int)pow(10,digits-1);
}

京公网安备 11010502036488号