leetcode面试150题day04

一、打家劫舍(动态规划)

class Solution 
{
public:
    int rob(vector<int>& nums)
    {
        if (nums.size()==0)
            return 0;
        if (nums.size() == 1)
            return nums[0];
        int n = nums.size();
        vector<int> dp(n, 0);
        //从后往前填表,从而避免递归的重复计算。最终结果是dp[0]。
        dp[n - 1] = nums[n - 1];
        dp[n - 2] = max(nums[n - 2], nums[n - 1]);

        for (int i = n - 3; i >= 0; i--)
        {
            dp[i] = max(nums[i] + dp[i + 2], dp[i + 1]);
        }
        return dp[0];
    }
};

//优化空间复杂度
class Solution 
{
public:
    int rob(vector<int>& nums) 
    {
        int n = nums.size();
        if (n == 0) return 0;
        if (n == 1) return nums[0];

        int prev1 = nums[n - 1];
        int prev2 = max(nums[n - 2], nums[n - 1]);

        for (int i = n - 3; i >= 0; --i) 
        {
            int curr = max(nums[i] + prev1, prev2);
            //后面的两个prev1和prev2决定curr,不需要dp数组的空间,用3个变量记录就行
            prev1 = prev2;
            prev2 = curr;
        }

        //因为最后把值赋给了prev2所以返回这个值
        return prev2;
    }
};

二、单词拆分(动态规划)

class Solution {
public:
    bool wordBreak(string& s, vector<string>& wordDict)
    {
        // 创建一个dp数组,初始化为false,大小为s.size()+1,因为多了一个空字符串的位置
        vector<bool> dp(s.size() + 1, false);
        // 空字符串可以被拆分,因此dp[0]设为true
        dp[0] = true;

        // 遍历字符串s的每一个位置
        for (int i = 0; i < s.size(); i++) 
        {
            // 如果dp[i]为false,说明从0到i的子字符串不能被拆分成字典中的单词,继续下一个i
            if (!dp[i])
                continue;

            // 遍历字典中的每一个单词
            for (auto& word : wordDict) 
            {
                // 检查当前单词是否可以匹配当前位置i开始的子字符串
                // 条件1:单词长度加上i不能超过s的长度
                // 条件2:s从位置i开始的子字符串与当前单词匹配
                if (word.size() + i <= s.size() && s.substr(i, word.size()) == word) 
                {
                    // 如果匹配成功,设置dp[i+word.size()]为true
                    dp[i + word.size()] = true;
                }
            }
        }
        // 返回dp数组最后一个位置的值,表示整个字符串是否可以被拆分
        return dp[s.size()];
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值