力扣训练——动态规划

本篇参照大佬博客练习题顺序,代码都是自打的,有些可能不是最优解。

目录

70. 爬楼梯

198. 打家劫舍

213. 打家劫舍 II

64. 最小路径和

62. 不同路径

303. 区域和检索 - 数组不可变

413. 等差数列划分

343. 整数拆分

279. 完全平方数

91. 解码方法

300. 最长递增子序列

646. 最长数对链

376. 摆动序列

1143. 最长公共子序列

416. 分割等和子集

494. 目标和

474. 一和零

322. 零钱兑换

518. 零钱兑换 II

377. 组合总和 Ⅳ

309. 最佳买卖股票时机含冷冻期

714. 买卖股票的最佳时机含手续费

123. 买卖股票的最佳时机 III

188. 买卖股票的最佳时机 IV

583. 两个字符串的删除操作

72. 编辑距离

650. 只有两个键的键盘


70. 爬楼梯

class Solution {
public:
    int climbStairs(int n) {
        int dp[n+10];
        dp[1]=1;
        dp[2]=2;
        for(int i=3;i<=n;i++)
        {
            dp[i]=dp[i-1]+dp[i-2];
        }
        return dp[n];
    }
};

198. 打家劫舍

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

213. 打家劫舍 II

class Solution {
public:
    int rob(vector<int>& nums) {
        int n=nums.size();
        int dp[n+1][2];
        if(n==0)
        return 0;
        if(n==1)
        return nums[0];
        if(n==2)
        return max(nums[0],nums[1]);
        dp[0][0]=0;
        dp[0][1]=0;
        for(int i=1;i<n;i++)
        {
            dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
            dp[i][1]=dp[i-1][0]+nums[i];
        }
        int a=max(dp[n-1][0],dp[n-1][1]);
        dp[0][0]=0;
        dp[0][1]=nums[0];
        for(int i=1;i<n-1;i++)
        {
            dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
            dp[i][1]=dp[i-1][0]+nums[i];
        }
        int b=max(dp[n-2][0],dp[n-2][1]);
        return max(a,b);
    }
};

64. 最小路径和

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int n=grid.size();
        int m=0;
        if(n!=0)
        m=grid[0].size();
        else
        return 0;
        int s=1e9+7;
        int dp[n+1][m+1];
        dp[0][0]=grid[0][0];
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(i==0&&j==0)
                continue;
                if(i==0)
                dp[i][j]=dp[i][j-1]+grid[i][j];
                else if(j==0)
                dp[i][j]=dp[i-1][j]+grid[i][j];
                else
                dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j];
            }
        }
        return dp[n-1][m-1];
    }
};

62. 不同路径

class Solution {
public:
    int uniquePaths(int m, int n) {
        long long ans=1;
        int k=n+m-2;
        n=min(n,m);
        for(int i=1;i<=n-1;i++)
        {
            ans*=(k-i+1);
            ans/=i;
        }
        return ans;
    }
};

303. 区域和检索 - 数组不可变

class NumArray {
public:
    int s[10001];
    NumArray(vector<int>& nums) {
        if(nums.size()>=1)
        s[0]=nums[0];
        for(int i=1;i<nums.size();i++)
        s[i]=s[i-1]+nums[i];
    }
    
    int sumRange(int i, int j) {
        if(i==0)
        return s[j];
        return s[j]-s[i-1];
    }
};

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray* obj = new NumArray(nums);
 * int param_1 = obj->sumRange(i,j);
 */

413. 等差数列划分

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A) {
        int n=A.size();
        if(n<3)
        return 0;
        //sort(A.begin(),A.end());
        int dp[n+2];
        dp[0]=0;
        dp[1]=0;
        int s=0;
        for(int i=2;i<A.size();i++)
        {
            if(A[i]-A[i-1]==A[i-1]-A[i-2])
            {
                dp[i]=dp[i-1]+1;
            }
            else
            dp[i]=0;
            s+=dp[i];
        }
        return s;
    }
};

343. 整数拆分

class Solution {
public:
    int integerBreak(int n) {
        int ans=n-1;
        for(int i=2;i<=n/2;i++)
        {
            int s=1;
            for(int j=1;j<n/i;j++)
            s*=i;
            ans=max(ans,max(s*(n%i+i),s*i*(n%i)));
        }
        return ans;
    }
};

279. 完全平方数

class Solution {
public:
    int numSquares(int n) {
        int b=n;
       while(n%4==0)
       {
           n/=4;
       }
       if(n%8==7)
       return 4;
       n=b;
       b=sqrt(n);
       if(b*b==n)
       return 1;
       for(int i=1;i*i<=n;i++)
       {
           int j=sqrt(n-i*i);
           if(j*j+i*i==n)
           return 2;
       }
       return 3;
    }
};

91. 解码方法

class Solution {
public:
    int numDecodings(string s) {
        int n=s.size();
        int dp[n+1];
        if(n==0)
        return 0;
        if(s[0]!='0')
        dp[0]=1;
        else
        dp[0]=0;
        for(int i=1;i<n;i++)
        {
            if(s[i]=='0'&&(s[i-1]>='3'||s[i-1]=='0'))
            return 0;
            if(s[i]=='0')
            {
                if(i>=2)
                dp[i]=dp[i-2];
                else
                dp[i]=1;
            }
            
            else if(s[i-1]=='0'||s[i-1]>='3')
            {
                dp[i]=dp[i-1];
            }
            else if(s[i-1]=='1')
            {
                dp[i]=dp[i-1];
                if(i>=2)
                dp[i]+=dp[i-2];
                else
                dp[i]++;
            }
            else if(s[i-1]=='2')
            {
                dp[i]=dp[i-1];
                if(s[i]<='6')
                {
                    if(i>=2)
                    dp[i]+=dp[i-2];
                    else
                    dp[i]++;
                }
            }

        }
        return dp[n-1];
    }
};

300. 最长递增子序列

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n=nums.size();
        int dp[n+1];
        for(int i=0;i<n;i++)
        dp[i]=1;
        int max1=1;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(nums[i]>nums[j])
                {
                    dp[i]=max(dp[i],dp[j]+1);
                    max1=max(max1,dp[i]);
                }
            }
        }
        return max1;
    }
};

646. 最长数对链

class Solution {
public:
    static bool cmp(vector<int>p, vector<int>q)
    {
        if(p[1]!=q[1])
        return p[1]<q[1];
        else
        return p[0]<q[0];
    } 
    int findLongestChain(vector<vector<int>>& pairs) {
        int n=pairs.size();
        int x;
        int max1=1;
        sort(pairs.begin(),pairs.end(),cmp);
        x=pairs[0][1];
        for(int i=1;i<n;i++)
        {
            if(pairs[i][0]>x)
            {
                max1++;
                x=pairs[i][1];
            }
        }
        return max1;
    }
};

376. 摆动序列

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int s1=1,s2=1;
        if(nums.size()==0)
        return 0;
        for(int i=1;i<nums.size();i++)
        {
            if(nums[i]>nums[i-1])
            s1=s2+1;
            else if(nums[i]<nums[i-1])
            s2=s1+1;
        }
        return max(s1,s2);
    }
};

1143. 最长公共子序列

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int n=text1.size(),m=text2.size();
        int dp[n+1][m+1];
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=m;j++)
            {
                dp[i][j]=0;
            }
        }
        int max1=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(text1[i-1]==text2[j-1])
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                }
                else
                {

                    dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
                }
                
            }
        }
        return dp[n][m];
    }
};

416. 分割等和子集

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int n=nums.size();
        int s=0;
        for(int i=0;i<n;i++)
        {
            s+=nums[i];
        }
        if(s%2)
        return false;
        bool dp[s+1];
        for(int j=0;j<=s;j++)
        {
            dp[j]=false;
        }
        dp[0]=true;
        for(int i=1;i<=n;i++)
        {
            for(int j=s;j>=nums[i-1];j--)
            {
                dp[j]=dp[j] || dp[j-nums[i-1]];
            }
        }
        return dp[s/2];
    }
};

494. 目标和

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int S) {
        int n=nums.size();
        int s=0;
        for(int i=0;i<nums.size();i++)
        s+=nums[i];
        if(s<S||(S+s)%2==1)
        return 0;
        int k=(S+s)/2;
        int dp[k+1];
        
        for(int i=0;i<=k;i++)
        dp[i]=0;
        dp[0]=1;
        for(int i=0;i<n;i++)
        {
            for(int j=k;j>=nums[i];j--)
            {
                dp[j]=dp[j]+dp[j-nums[i]];
            }
        }
        return dp[k];
    }
};

474. 一和零

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        int l=strs.size();
        int dp[m+1][n+1];
        memset(dp,0,sizeof(dp));
        for(int i=0;i<l;i++)
        {
            int s1=0,s2=0;
            for(int j=0;j<strs[i].size();j++)
            {
                if(strs[i][j]=='0')
                s1++;
                else
                s2++;
            }
            for(int j=m;j>=s1;j--)
            {
                for(int k=n;k>=s2;k--)
                {
                    dp[j][k]=max(dp[j][k],dp[j-s1][k-s2]+1);
                }
            }
        }
        return dp[m][n];
    }
};

322. 零钱兑换

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        int dp[amount+1];
        for(int i=0;i<=amount;i++)
        dp[i]=1000000000;
        dp[0]=0;
        for(int i=0;i<coins.size();i++)
        {
            for(int j=coins[i];j<=amount;j++)
            {
                dp[j]=min(dp[j],dp[j-coins[i]]+1);
            }
        }
        if(dp[amount]==1000000000)
        return -1;
        else
        return dp[amount];
    }
};

518. 零钱兑换 II

class Solution {
public:
    int change(int amount, vector<int>& coins) {
        int n=coins.size();
        int dp[amount+1];
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(int i=0;i<n;i++)
        {
            for(int j=coins[i];j<=amount;j++)
            {
                dp[j]+=dp[j-coins[i]];
            }
        }
        return dp[amount];
    }
};

377. 组合总和 Ⅳ

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        int n=nums.size();
        long long dp[target+10];
        for(int i=0;i<=target+1;i++)
        dp[i]=0;
        dp[0]=1;
        long long mod=1e18+7;
        sort(nums.begin(),nums.end());
        for(int i=1;i<=target;i++)
        {
            for(int j=0;j<n&&i>=nums[j];j++)
            {
                dp[i]+=dp[i-nums[j]];
                dp[i]%=mod;
            }
        }
        return dp[target];
    }
};

309. 最佳买卖股票时机含冷冻期

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n=prices.size();
        if(n==0)
        return 0;
        int dp[n+1][3];
        dp[0][0]=0;
        dp[0][1]=-prices[0];
        dp[0][2]=0;
        for(int i=1;i<n;i++)
        {
            dp[i][0]=max(dp[i-1][0],dp[i-1][2]);
            dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
            dp[i][2]=dp[i-1][1]+prices[i];
        }
        int x=max(dp[n-1][0],max(dp[n-1][1],dp[n-1][2]));
        return x;
    };

};

714. 买卖股票的最佳时机含手续费

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        int n=prices.size();
        int dp[n+1][2];
        dp[0][1]=-fee-prices[0];
        dp[0][0]=0;
        for(int i=1;i<n;i++)
        {
            dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);
            dp[i][1]=max(dp[i-1][0]-fee-prices[i],dp[i-1][1]);
        }
        return max(dp[n-1][0],dp[n-1][1]);
        
    }
};

123. 买卖股票的最佳时机 III

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n=prices.size();
        if(n==0)
        return 0;
        int dp[n+1][5];
        dp[0][0]=0;
        dp[0][1]=-prices[0];
        dp[0][2]=0;
        dp[0][3]=-10000000;
        dp[0][4]=0;
        for(int i=1;i<n;i++)
        {
            dp[i][0]=dp[i-1][0];
            dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
            dp[i][2]=max(dp[i-1][2],dp[i-1][1]+prices[i]);
            dp[i][3]=max(dp[i-1][3],dp[i-1][2]-prices[i]);
            dp[i][4]=max(dp[i-1][4],dp[i-1][3]+prices[i]);

        }
        int x=max(max(dp[n-1][0],max(dp[n-1][3],dp[n-1][4])),max(dp[n-1][1],dp[n-1][2]));
        return x;
    };

};

188. 买卖股票的最佳时机 IV

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n=prices.size();
        if(n==0)
        return 0;
        if(k==0)
        return 0;
        int dp[n+1][k+1][2];
        dp[0][1][1]=-prices[0];
        dp[0][1][0]=0;
        int mod=1e9+7;
        for(int i=2;i<=k;i++)
        {
            dp[0][i][0]=0;
            dp[0][i][1]=-mod;
        }
        for(int i=1;i<n;i++)
        {
            dp[i][1][1]=max(dp[i-1][1][1],-prices[i]);
            dp[i][1][0]=max(dp[i-1][1][0],dp[i-1][1][1]+prices[i]);
            for(int j=2;j<=k;j++)
            {
                if(j<=i+1)
                {
                    dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j-1][0]-prices[i]);
                    dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1]+prices[i]);
                }
                else
                {
                    dp[i][j][0]=0;
                    dp[i][j][1]=-mod;
                }
                //cout<<dp[i][j][1]<<" "<<dp[i][j][0]<<endl;
            }
        }
        int x=0;
        for(int i=1;i<=k;i++)
        {
            x=max(x,dp[n-1][i][0]);
        }
        return x;
    }
};

583. 两个字符串的删除操作

class Solution {
public:
    int minDistance(string word1, string word2) {
        int n=word1.size(),m=word2.size();
        int dp[n+1][m+1];
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=m;j++)
            {
                dp[i][j]=0;
            }
        }
        int max1=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(word1[i-1]==word2[j-1])
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                }
                else
                {

                    dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
                }
                
            }
        }
        return n+m-2*dp[n][m];
    }
};

72. 编辑距离

class Solution {
public:
    int minDistance(string word1, string word2) {
        int n=word1.size(),m=word2.size();
        int dp[n+1][m+1];
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=m;j++)
            {
                dp[i][j]=0;
            }
        }
        for(int i=1;i<=n;i++)
        {
            dp[i][0]=i;
        }
        for(int i=1;i<=m;i++)
        {
            dp[0][i]=i;
        }
        int max1=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(word1[i-1]==word2[j-1])
                {
                    dp[i][j]=dp[i-1][j-1];
                }
                else
                {

                    dp[i][j]=min(dp[i-1][j-1],min(dp[i][j-1],dp[i-1][j]))+1;
                }
                
            }
        }
        return dp[n][m];
    }
};

650. 只有两个键的键盘

class Solution {
public:
    int minSteps(int n) {
        if(n==1)
        return 0;
        int s=0;
        int k=1;
        s++;
        s++;
        k++;
        while(n%k!=0)
        {
            s++;
            k++;
        }
        s+=minSteps(n/k);
        return s;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
左程云在动态规划题型方面有一些相关的讲解和课程。动态规划是一种常见的算法设计技巧,可以解决一些具有重叠子问题性质的问题。通过分解问题为子问题,然后根据子问题的解推导出原问题的解。引用中提到了左程云的算法课堂上有动态规划相关的题目。还有一些其他的题目也可以在LeetCode上找到,比如[1108. IP 地址无效化(简单)]、[344. 反转字符串(简单)]以及[剑指 Offer 58 - I. 翻转单词顺序(简单)]等。所以,如果对动态规划感兴趣,可以参考左程云的课堂和LeetCode上的相关题目进行练习。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [出自算法之神“左程云”的这本《算法面试指南》被LeetCode官推,秀我一脸~](https://blog.csdn.net/SharingOfficer/article/details/121523204)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [左程云leetcode-LeetCode:力扣解决方案](https://download.csdn.net/download/weixin_38556416/19925757)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值