①报数
报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1. 1
2. 11
3. 21
4. 1211
5. 111221
1
被读作 "one 1"
("一个一"
) , 即 11
。11
被读作 "two 1s"
("两个一"
), 即 21
。21
被读作 "one 2"
, "one 1"
("一个二"
, "一个一"
) , 即 1211
。
给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。
注意:整数顺序将表示为一个字符串。
示例 1:
输入: 1
输出: "1"
示例 2:
输入: 4
输出: "1211"
1.基本思路就是就是对于前一个数,找出相同元素的个数,把个数和该元素存到新的string里:
class Solution {
public:
string countAndSay(int n) {
if (n == 1)
return "1";
string s = "1";
while (--n) //一直往后推,直到所需报数值
{
string cur = ""; //当前报数
for (int i = 0;i < s.size(); ++i) //对于当前报数,遍历-操作得到下一报数值
{
int cnt = 1;
while (i + 1 < s.size() && s[i] == s[i+1]) //对于当前字符如果跟下一字符相同,则计数cnt加1
{
++cnt;
++i;
}
cur += to_string(cnt) + s[i]; //计数cnt的值加上当前字符
}
s = cur; //得到下一报数值
}
return s;
}
};
②最大子序和
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
1.暴力解法,遍历得出所有可能的结果,并且每种情况都与一个给定的max比较,若比max大则将该值赋給max(时间复杂度O(n2):
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int sum , max = nums[0];
for (int i = 0; i < nums.size(); ++i) //两层遍历得到所有序列和,并判断得出最大序列和
{
sum = 0;
for (int j = i; j < nums.size(); ++j)
{
sum += nums[j];
if (sum > max)
max = sum;
}
}
return max;
}
};
2.时间复杂度O(n)的解法,遍历数组,如果序列和sum小于0,则将当前数组的值赋給sum,否则加上该数组元素值,然后sum跟给定的max比较,若比max大则将该值赋給max:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.empty())
return 0;
if (nums.size() == 1)
return nums[0];
int sum = nums[0]; //初始化序列和为nums[0]
int max = nums[0]; //初始化max为nums[0]
int i = 1;
while (i < nums.size())
{
if (sum < 0) //如果sum小于0,则将当前数组值赋給sum,寻找更大序列和
sum = nums[i];
else
sum += nums[i]; //sum大于0,则加上当前数组值
if (sum > max)
max = sum;
++i;
}
return max;
}
};