剑指offer系列24:连续子数组的最大和

初次看到这个题的时候,我觉得很复杂,因为不知道所求的子数组的长度,而且里有负数增加了难度。看了答案之后发现竟然可以用这么简单的算法做出来,答案里说用的是贪心算法。

 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4 class Solution {
 5 public:
 6     int FindGreatestSumOfSubArray(vector<int> array) {
 7         if (array.empty())
 8             return 0;
 9         int sum = 0, maxsum = 0,maxnum=INT_MIN;
10         for (int i = 0; i < array.size(); i++)
11         {
12             //sum = sum + array[i];
13             sum += array[i];
14             if (sum < 0)
15                 sum = 0;
16             else if (sum > maxsum)
17                 maxsum = sum;
18             if (array[i] > maxnum)
19                 maxnum = array[i];
20         }
21         return (maxsum>0)?maxsum:maxnum;
22     }
23 };
24 int main()
25 {
26     vector<int> test{ 1,-2,3,10,-4,7,2,-5 };
27     Solution so;
28     cout << so.FindGreatestSumOfSubArray(test) << endl;
29     return 0;
30 }

剑指offer上说这个题也可以用动态规划的思路去做,但是代码是一样的。动态规划和贪心算法都是很常考的算法。

接下来写一个时间复杂度低的算法,总体来讲就是找到规律,用递归的方式去一层一层的解,有点像分治法。

 1 #include<iostream>
 2 #include<string>
 3 //#include <sstream>
 4 using namespace std;
 5 class Solution {
 6 public:
 7     int NumberOf1Between1AndN_Solution(int n)
 8     {
 9         char c[50];
10         sprintf_s(c, "%d", n);//将数字转成字符串
11         int re=Find1(c);
12         return re;
13     }
14     int Find1(const char *s)
15     {
16         if (!s || *s<'0' || *s>'9' || *s == '')
17             return 0;
18         //char first = s[0];
19         int first = *s - '0';//first需要设置成整型,后面计算需要用到,第一位减去0刚好是他的整型的数
20         unsigned int length = static_cast<unsigned int>(strlen(s));//强制表达式格式转化
21 
22         //递归的结束条件
23         if (length == 1 &&first==0)//个位是0的时候返回0
24             return  0;
25         if (length == 1 && first>0)//个位大于0说明至少有一个1,返回1
26             return 1;
27         //char first = s[0];
28         int highbit = 0, midbit = 0, lowbit = 0;
29         //最高位为1的个数
30         //假设数字为21345,将其分为两步分,分别是1346~21345和1~1345
31         if (first >1)
32             highbit = powerbase10(length - 1);
33         else
34             if(first==1)
35             {
36                 highbit = atoi(s + 1) + 1;
37             }
38         //21345中除了最高位之外的其余4位为1的数量,排列组合,C4-1,即在四位中挑出一位写上,剩下的位的数字为C10-1
39         midbit = first*(length-1)*powerbase10(length - 2);
40 
41         //1~1345中的1的数目
42         lowbit = Find1(s+1);
43 
44         return highbit + midbit + lowbit;
45     }
46     int powerbase10(int n)
47     {
48         int re=1;
49         for (int i = 0; i < n; i++)
50             re *= 10;
51         return re;
52     }
53 };
54 int main()
55 {
56     Solution so;
57     cout << so.NumberOf1Between1AndN_Solution(100) <<endl;
58     return 0;
59 }
原文地址:https://www.cnblogs.com/neverland0718/p/11164369.html