[每日一题]动态规划一位数组的解题:台阶问题,打家劫舍

台阶:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 1 阶
2.  2 阶
示例 2:

输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 1 阶
2.  1 阶 + 2 阶
3.  2 阶 + 1 阶

来源:力扣(LeetCode)
 

class Solution {
    public int climbStairs(int n) {
        //动态规划
        if(n<=2){
            return n;
        }
        int p1=2,p2=1,cur=0;
        for(int i=2;i<n;i++){
            cur=p1+p2;
            p2=p1;
            p1=cur;

        }
        return p1;
    }
}

打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

 

示例 1:

输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:

输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。

来源:力扣(LeetCode)

class Solution {
    public int rob(int[] nums) {
        int p1=0,p2=0;
        for(int i=0;i<nums.length;i++){
            int cur=Math.max(p2+nums[i],p1);
            p2=p1;
            p1=cur;
        }
        return p1;
    }
}

打家劫舍2:

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

示例 1:

输入: [2,3,2]
输出: 3
解释: 你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
示例 2:

输入: [1,2,3,1]
输出: 4
解释: 你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。

来源:力扣(LeetCode)
 

class Solution {
    public int rob(int[] nums) {
        int n=nums.length;
        if(nums==null){
            return 0;
        }
        if(n==1){
            return nums[0];
        }
        return Math.max(myrob(nums,0,n-2),myrob(nums,1,n-1));

    }
    public int myrob(int[] nums,int first,int last){
        int p1=0,p2=0;
        for(int i=first;i<=last;i++){
            int cur=Math.max(p1,p2+nums[i]);
            p2=p1;
            p1=cur;
        }
        return p1;
    }
}

总结:

这三道题的核心就是动态规划。

跑楼梯的思路就是斐波那契数列,可以采用递归,但是递归会有内存问题。另一种解法就是动态规划,1阶楼梯对应的是1种办法,2对应的两种办法,3对应的是3中办法。4对应5种。。。所以这个核心的思路就是,3之后,是前俩的和。

p1=2;p2=1;

cur=p1+p2;

p2=p1;
p1=cur;

随着循环,依次向后滚动着赋值,第一次得到3级台阶的cur;循环赋值 则是为第四级台阶计算做准备的 3+2 也就是 把p1的2 给p2;cur赋给p1的是第三级台阶的值。。。最后其实返回p1,或者cur都是可以的。

第二题打家劫舍也是这样的核心思想

一位数组依次间隔相加,1、3、5、7     2、4、6......  

循环,比较下标为奇数和下标为偶数的值的和,赋值给cur;

第一次 就是 p2+num[0];然后就是 p1 的0的值 给p2;cur的值给p1;为第二次循环做准备

第二次求出来的就是下标1所对应的值,和下标是0 的值比较(当前的p1) 谁大 谁的值就给cur

第三次循环到下标是2的数值,和p2加 也就是和上一轮的p1加,这个p1的值 是在第一次循环是 cur的值 也就是 下标是0 的第一个数字,所以,在这里0he2的值要和下标1的比较 。。。这样一次走下去 直到最后一个数遍历完。得到最后的值 比较 谁大就返回谁 

第三题环状的 假如8个数字  0-7的下标 01234567(0) 从0开始的话     0 2 4 6   从1开始的话  1 3 5 7 

7个数字时:0-6

0123456(0)  0: 0 2 4   取不到6 因为6 紧挨着0             1:1 3 5

所以就得标记出开头和结尾 适用于偶数个数字 奇数个数字的普世情况

下标0开始的时候 最后的数值  长度-2 (倒数第二个数) 下标1开始的时候 最后能得到 长度-1(最后一个数)就可以了  

然后在进行第二题那样的判断  

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值