LeetCode java day9

LeetCode java day9

**213. 打家劫舍 II**

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

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



害。。变成环了就得考虑更多了,一开始想着直接把结尾元素移到最前方,然后num012比较大小啥的,果不其然,一半的例子会出大问题。。。。

class Solution {
    public int rob(int[] nums) {
        int len=nums.length;
        if(len==1){
            return nums[0];
        }
        if(len==2){
            return Math.max(nums[1],nums[0]);
        }
        int [][]dp=new int[101][2];
               dp[0][0]=0;//不选第一个元素
               dp[0][1]=nums[0]; //选一个元素
        for(int i=1;i<len;i++){
            for(int j=0;j<2;j++){
                if(i==1){
                    if(j==1){
                        dp[i][j]=nums[0];
                    }else
                    {
                        dp[i][j]=nums[1];
                    }
                }
                else if(j==1&&i==len-1){
                    dp[i][j]=dp[i-1][j];//由于选了第一个元素就不能选最后一个了
                }else{
                    dp[i][j]=Math.max(dp[i-1][j],(dp[i-2][j]+nums[i]));//安心地状态转移方程
                }
            }
        
        }
        return Math.max(dp[len-1][0],dp[len-1][1]);
    }
}

91. 解码方法

一条包含字母 A-Z 的消息通过以下映射进行了 编码 :

'A' -> "1"
'B' -> "2"
...
'Z' -> "26"

要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,"11106" 可以映射为:

  • "AAJF" ,将消息分组为 (1 1 10 6)
  • "KJF" ,将消息分组为 (11 10 6)

注意,消息不能分组为 (1 11 06) ,因为 "06" 不能映射为 "F" ,这是由于 "6""06" 在映射中并不等价。

给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。

题目数据保证答案肯定是一个 32 位 的整数。

示例 1:

输入:s = "12"
输出:2
解释:它可以解码为 "AB"(1 2)或者 "L"(12)。

示例 2:

输入:s = "226"
输出:3
解释:它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。

示例 3:

输入:s = "06"
输出:0
解释:"06" 无法映射到 "F" ,因为存在前导零("6" 和 "06" 并不等价)。

emmm,一开始没注意,看成是输出字母最多。


下面这里错的我懵逼一脸

 if(s.charAt(i)==s.charAt(i-1)&&s.charAt(i)=='0'){
                return 0;
            }
dp[i]+=dp[i-1];//应该在这里再加个判断为零的条件。
解答错误
179 / 269 个通过的测试用例
官方题解
输入
s =
"10"
添加到测试用例
输出
2
预期结果
1

考虑多了把关键的忘记了

 if(s.charAt(i)=='0'&&s.charAt(i-1)=='0'){
                    return 0;
                }
这一句也是完全多余的,
class Solution {
        public  int numDecodings(String s) {
            int[]dp=new int[101];
            if(s.length()==0||s.charAt(0)=='0'){
                return 0;
            }
            dp[0]=1;//开头不为零且长度不为1的话至少有一种
            for (int i = 1; i <s.length() ; i++) {
                if(s.charAt(i)!='0'){
                    dp[i]+=dp[i-1];//等于0的话就映射不了了,如果下一个再为0直接鸡鸡了
                }
                if(s.charAt(i-1)=='1'||s.charAt(i-1)=='2'){
                    int value = (s.charAt(i-1)-'0')*10 +(s.charAt(i)-'0');
                    if(value<=26){
                        if(i==1){
                            dp[i]++;
                        }else {
                            dp[i]+=dp[i-2];
                        }
                    }
                }
            }
            return dp[s.length()-1];
        }
    }

感觉动态规划真的好神奇,大多数时候也很难想到。。。。

现在就边界问题和特殊情况想的还行,状态转移的处理就拉跨了。QAQ,看看大佬们的多学习学习,然后多练习了。
害…早上刷SSM的时候还迫不及待想刷算法(也可能是想念springboot,大抵是都有)了,结果刷动态规划又开始想念SSM了,艹。
手撕不了红黑树,偶尔撕撕动态规划中等题吧?(加油(ง •_•)ง)


更新一条。看了看评论区,大家都是栽在边界条件啊,hhh。本人太弱了一开始想着能不能暴力一下,就把边界条件想得挺全的(大佬们状态转移五分钟,边界处理两小时,咱边界处理五分钟,状态转移两小时(开个玩笑O(∩_∩)O))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值