代码随想录算法训练营day48|198.打家劫舍213.打家劫舍II337.打家劫舍III剑指Offer46.把数字翻译成字符串48.最长不含重复字符的子字符串

198.打家劫舍

题目链接

dp[i]表示,考虑到下标i处所偷的最大金额,仅仅是考虑到,并不一定取该元素。

注意只有一个元素的时候要特殊处理,先判断一下,不然会溢出。有两个元素的情况就不用处理了,因为后面初始化的时候已经取了max。

class Solution {
public:
    int rob(vector& nums) {
        if(nums.size()==1) return nums[0];
        vector dp(nums.size(),0);
        dp[0]=nums[0];
        dp[1]=max(nums[0],nums[1]);
        for(int i=2;i

213.打家劫舍II

题目链接

思路:把环形转换成线性,考虑两种情况,一是不考虑第一个元素,二是不考虑最后一个元素。

class Solution {
public:
    int robrange(vector& nums,int start,int end){
        if(start==end) return nums[start];
        vector dp(nums.size()-1,0);//第一处错,不应该是end-1
        dp[0]=nums[start];
        dp[1]=max(nums[start],nums[start+1]);
        for(int i=2;i& nums) {
        if(nums.size()==1) return nums[0];
        return max(robrange(nums,0,nums.size()-2),robrange(nums,1,nums.size()-1));
    }
};

这道题还是有待继续研究,改了好几次才通过,因为我的写法是dp数组的下标和nums数组的下标是不同步的,处理的细节要多一点,同步的写法可以参考卡哥的代码。

337.打家劫舍III

题目链接

树形dp。用一个长度为2的一维数组即可,递归的时候系统栈里会帮我们保存每一层的参数。

class Solution {
public:
    vector robtree(TreeNode* cur){
        if(cur==NULL) return vector{0,0};
        vector leftdp=robtree(cur->left);
        vector rightdp=robtree(cur->right);
        int val0=max(leftdp[0],leftdp[1])+max(rightdp[0],rightdp[1]);//左右子节点偷不偷取决于哪个是最大值
        int val1=cur->val+leftdp[0]+rightdp[0];
        return {val0,val1};//上面写了int了,所以就不用写vector了
    }
    int rob(TreeNode* root) {
        vector result=robtree(root);
        return max(result[0],result[1]);
    }
};

剑指 Offer 46. 把数字翻译成字符串

题目链接

思路:本题主要是递推公式。dp[i]表示到下标为i处一共有多少种翻译方法。最后两位一共有两种状态,介于0-25之间和不介于0-25之间,根据这两种情况,如果介于的话,dp[i]=dp[i-1]+dp[i-2](类似于爬楼梯),不介于的话只能当个字符进行翻译,dp[i]=dp[i-1]。

class Solution {
public:
    int translateNum(int num) {
        string str=to_string(num);
        if(str.size()==1) return 1;
        vector dp(str.size());
        dp[0]=1;
        if((str[0]=='1')||(str[0]=='2'&&str[1]<='5')) dp[1]=2;
        else{
            dp[1]=1;
        }
        for(int i=2;i

注意函数to_string的使用。

注意开始要进行判断,如果就一位的话,后面写str[1]会溢出。

注意判断条件,如果前一位是1的话,后一位是什么都无所谓,如果是2的话,后一位(当前位)只能<='5'。

48.最长不含重复字符的子字符串

题目链接

思路:双指针+哈希表。这个解法还是很巧妙的。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map hash;
        int res=0;
        for(int i=0,j=0;j1){//这个while循环相当于去重
                hash[s[i]]--;
                i++;//这个不能放前面,因为放前面的话,i开始指向的位置还没减呢
            }
            res=max(res,j-i+1);
        }
        return res;
    }
};

好像还有滑动窗口的解法,还有待研究。

你可能感兴趣的:(算法,leetcode,动态规划)