本篇参照大佬博客练习题顺序,代码都是自打的,有些可能不是最优解。
目录
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;
}
};