OJ - 53 Maximum Subarray && 70 - Climbing Stairs

这两个是关于动态规划的题目。

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个状态只需要前两个状态的值,我们不需要额外的空间来保存所有的状态,只需要三个变量就可以完成我们的任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值