【C++】力扣刷题 1.摆动序列 2.分饼干 3.最大子数组和 4.买卖股票的最佳时机 II 5.跳跃游戏 6.跳跃游戏 II

目录

1.摆动序列

 2.分饼干

 3.最大子数组和

4.买卖股票的最佳时机 II

5.跳跃游戏

 6.跳跃游戏 II


1.摆动序列

可以两种方法解决

  • 动归

设置两种状态

dp[i][0]:表示下标i作为波峰,前i个数中的最长的摆动子序列长度

dp[i][1]:表示下标i作为波谷,前i个数最长的摆动子序列长度

因为dp[0][0]和dp[0][1]本身就可以作为长度为1的摆动子序列,所以设置为1 

 

int dp[1001][2];
int wiggleMaxLength(vector<int>& nums) {
    memset(dp, 0, sizeof(dp));
    dp[0][0] = dp[0][1] = 1;
    for (int i = 0; i < nums.size(); i++)
    {
        dp[i][0] = dp[i][1] = 1;
        for (int j = 0; j < i; j++)
        {
            if (nums[j] < nums[i])
                dp[i][0] = max(dp[j][1] + 1, dp[i][0]);
        }
        for (int j = 0; j < i; j++)
        {
            if (nums[j] > nums[i])
                dp[i][1] = max(dp[j][0] + 1, dp[i][1]);
        }
    }
    return max(dp[nums.size() - 1][1], dp[nums.size() - 1][0]);
  • 贪心算法 

 

int wiggleMaxLength(vector<int>& nums) {
    if (nums.size() <= 1) return nums.size();
    int ans = 1;
    int pregap = 0, curgap = 0;
    for (int i = 0; i < nums.size() - 1; i++)
    {
        curgap = nums[i + 1] - nums[i];
        if ((pregap <= 0 && curgap > 0) || (pregap >= 0 && curgap < 0))
        {
            ans++;
            pregap = curgap;
        }
    }
    return ans;
}

 2.分饼干

 

首先把饼干和小孩的胃口排序,保证小饼干可以喂给小胃口的孩子

用for遍历饼干,保证每一个饼干都有被分出去的机会

用一个下标index遍历小孩,如果小孩的胃口g[i]和饼干s[i]保持g[i]<=s[i]的关系,那么这个饼干就可以被给

 int findContentChildren(vector<int>& g, vector<int>& s) {
    int index=0;
    sort(s.begin(),s.end());
    sort(g.begin(),g.end());
    for(int i=0;i<s.size();i++)
    {
        if(index<g.size()&&g[index]<=s[i]) index++;
    }
    return index;
    }

 3.最大子数组和

这个题和第一题的dp状态法差不多,把 dp[i]表示下标为i处的最大子数组的和,然后用一个MAX元素把dp里面最大的元素记录下来,就是最大的子数组和,因为每个元素都精确到下标,所以dp中的每一个元素都是连续子数组和

 int maxSubArray(vector<int>& nums) {
        if(nums.empty()) return 0;
    vector<int> dp(nums.size());
    dp[0]=nums[0];
    int MAX=nums[0];
    for(int i=1;i<nums.size();i++)
    {
        dp[i]=max(dp[i-1]+nums[i],nums[i]);
        if(dp[i]>MAX) MAX=dp[i]; 
    }
    return MAX;
    }

4.买卖股票的最佳时机 II

因为题目规定了可以当天买卖,所以只要今天比昨天大,那就+=差值 ,相当于昨天买今天卖,如果有很多个今天比昨天大的情况

比如 [7,1,5,6]  ans+=5-1  第三天卖,第二天买

ans+=6-5 第四天卖第三天买

总体来看就是第二天买,第三天卖了又买(买回来是因为明天还有红利),第四天再卖

int maxProfit(vector<int>& prices) {
      int ans=0;
      for(int i=1;i<prices.size();i++)
      {
          if(prices[i]>prices[i-1])
          ans+=prices[i]-prices[i-1];
      }
return ans;
    }

5.跳跃游戏

首先你在第一格,往后遍历的时候每次先-1步数,如果当前下标的最远步数比你目前能跳的步数(cur)还大,那么cur=nums[i]

 bool canJump(vector<int>& nums) {
    int cur=nums[0];
    int i=1;
    for(;cur && i<nums.size();i++)
    {
        cur--;
        if(cur<nums[i]) cur=nums[i];
    }
    return i==nums.size();
    }

 6.跳跃游戏 II

用dp[i]状态记录到达下标i需要的最少步数

如果只有一个元素,不需要跳

step数组记录每个状态所能到达的最大位置

    int jump(vector<int>& nums) {
        if(nums.size()==1) return 0;
vector<int> dp(nums.size());
dp[0]=0;
vector<int> step(nums.size());
step[1]=nums[0];
for(int i=1;i<nums.size();i++)
{
    dp[i]=step[dp[i-1]]>=i?dp[i-1]:dp[i-1]+1;
    if(dp[i]+1 < nums.size())
    step[dp[i]+1]=max(step[dp[i]+1],i+nums[i]);

}
return dp[nums.size()-1];
    }

猜你喜欢

转载自blog.csdn.net/weixin_71138261/article/details/129966928