LeetCode - 198. House Robber & 213. House Robber II - C++

 昨天腾讯笔试题:n个整数的圆环中取m个数,不能取相邻的,求可取出的最大和,同学提醒是LeetCode#213相似题目。

#213是#198的变式,所以又做了一下198. House Robber

// dp数组
class Solution {
public:
    int rob(vector<int>& nums) {
        int length = nums.size();
        if(length == 0) return 0;
        if(length == 1) return nums[0];
        
        vector<int> dp(length, 0);
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        
        for(int i=2; i<length; i++) {
            dp[i] = max(nums[i]+dp[i-2], dp[i-1]);
        }
        
        return dp[length-1];
    }
};
// 两个变量代替dp数组,Runtime变快了一半
class Solution {
public:
    int rob(vector<int>& nums) {
        int length = nums.size();
        if(length == 0) return 0;
        if(length == 1) return nums[0];
        
        // length==2, i==1
        int minus2 = 0;
        int minus1 = nums[0];
        int current = max(nums[0], nums[1]);
        
        for(int i=2; i<length; i++) {
            minus2 = minus1;
            minus1 = current;
            current = max(nums[i]+minus2, minus1);
        }
        
        return current;
    }
};

213. House Robber II

相比于#198,加了一步把圆圈化成直线,转换为#198.代码比较简单,max(选第一个, 不选第一个)。我称为“化圈为直法”。

class Solution {
public:
    int rob(vector<int>& nums) {
        int length = nums.size();
        if(length == 0) return 0;
        if(length == 1) return nums[0];
        return max(rob(nums, 0, length-2), rob(nums, 1, length-1)); 
    }
    // 去环后
    int rob(vector<int> nums, int low, int high) {
        if(low == high) return nums[low];
        vector<int> dp(high+1, 0);
        dp[low] = nums[low];
        dp[low+1] = max(nums[low], nums[low+1]);
        for(int i=low+2; i<=high; i++) {
            // 选nums[i]或不选
            dp[i] = max(nums[i] + dp[i-2], dp[i-1]);
        }
        return dp[high];
    }
};

感想:首先说说腾讯笔试感想。笔试前准备不足,比较仓促,笔试开始时脑袋空空连题目都看不进去,对输入输出语法也不太明白,后面更是有一道题测试用例没转过来弯。对于这种情况以后要避免,要保持每天写点代码的状态,笔试前时间要宽松,做好心理准备。很多题目稍微复杂就会产生恐惧心理,还是因为基本功不扎实,要多做题+温故知新。

用半个小时做出了第一道剑指Offer上几乎原题的约瑟夫环问题,心态好了一点点。后面的一个半小时来回看后面题目。第二道题题目虽长但是并不复杂,在最后求逐步增长数组的第k小,k也逐步++,不知道怎么解决,用了复制、sort函数。超时,case过了80%,不知道这种情况怎么给分。

再说这道题,是动态规划,也考虑到了动态规划,但是因为还不够熟练所以思考不清楚。

LeetCode这道题的所得:

1.化圈为直

3.对于输入的简单特殊情况处理,可能会重复,没关系,先写上,大不了就是代码不简洁问题,到最后再改善。

4.边界条件的处理很多时候跟越界访问有关,如果不处理边界很容易导致错误。

2.Math是Java的东西,c++取最大值只需要max(x1, x2)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值