这两个是关于动态规划的题目。
53 : Description:
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [-2,1,-3,4,-1,2,1,-5,4],
the contiguous subarray [4,-1,2,1] has the largest sum = 6.
描述:
在一个数组中找出拥有最大和的连续子数组(至少拥有一个数字)
例子: 一个数组为[-2,1,-3,4,-1,2,1,-5,4],那么拥有最大连续和的数组为:[4,-1,2,1] 最大和为6。
只用返回最大和,不用记录子数组的起始位置和结束位置。
这个题满足使用动态规划的两个条件:
1.最优子结构
2.重叠子问题
所以我们需要选取动态规划来解决这个问题。
思路:题目不要求保存下标,那么我们只需要计算最大和即可,那么我们就需要两个数来辅助我们:max 和 current,我们可以得到递归关系:
d[i] = Max(d[i-1] + current, max)
则我们可以得到下面的代码:
int maxSubArray(vector<int>& nums) {
int size = nums.size();
int max = nums[0];
int current = nums[0];
for (int i = 1; i < size; ++i) {
if (current < 0 && nums[i] > current) {
current = nums[i];
} else {
current += nums[i];
}
max = max > current ? max : current;
}
return max;
}
其中,for循环里面的第一个if是用来寻找最大子数组的起始数字的:
当current小于0的时候,意味着当前子数组的和已经小于0了,如果当前数组元素的值比当前子数组的和要大的话,那么我们需要从当前数组元素重新开始计算子数组的和。
第二个if 用来判断 最大子数组的和是否需要替换。
70:
Description:
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
描述:
假设我们在爬楼梯,楼梯有n阶,每一次我们只能跨1层或者2层,有多少种爬到顶的方式。(n是正整数)
得到这个题目,我们可以从简单的数字开始分析:
1. n == 1,那么只有一种方式:跨一层
2. n == 2,那么有两种方式:2 * 跨一层 + 1 * 跨两层
3. n == 3,从第二层按照n == 1 的方式跨上来,从第一层按照 n == 2 的方式跨上来
4. n == 4,从第三层按照 n == 1的方式跨上来,从第二层按照 n == 2 的方式跨上来
5. …….
那么我们就可以得到一个关系式:
d[i] = d[i-1] + d[i-2]
代码为:
int climbStairs(int n) {
if (n < 3) {
return n;
}
int a = 1;
int b = 2;
for (int i = 3; i <= n; ++i) {
int c = a + b;
a = b;
b = c;
}
return b;
}
因为第i个状态只需要前两个状态的值,我们不需要额外的空间来保存所有的状态,只需要三个变量就可以完成我们的任务。