贪心

贪心

121.买卖股票的最佳时机

image

class Solution {
public:
    int maxProfit(vector<int>& prices) {
     //只需要后面卖出的价格>前面买入价格(不用连续区间递增的)
     int minprice=1e9;
     int maxprofit=0;
     for(auto i:prices){
        maxprofit=max(maxprofit,i-minprice);//当前价格-之前最低价格
        minprice=min(minprice,i);
     }
     return maxprofit;
    }
};

 

55.跳跃游戏

image

方法一:

遍历每一个下标看能不能到达

每次要记录当前能到达的最远距离,只有当前坐标小于等于其前面点所到达的最远距离才可以

 

class Solution {
public:
    bool canJump(vector<int>& nums) {
   //方法一:遍历每个点看是否能到
   int reachmax=0;
   for(int i=0;i<nums.size();i++){
    if(i>reachmax){
        return false;
    }
    //用当前点更新能到最远距离
    reachmax=max(reachmax,i+nums[i]);
   }
   return true;
    }
};

方法二:看最远能否到终点

class Solution {
public:
    bool canJump(vector<int>& nums) {
   //方法二:看是否能到达终点(最远是否>=终点)
   int reachmax=0;
  for(int i=0;i<=reachmax&&reachmax<nums.size()-1;i++){
    reachmax=max(reachmax,i+nums[i]);
  }
  return reachmax>=nums.size()-1;
    }
};

方法三:反推法->看从后往前是否能到达起点

class Solution {
public:
    bool canJump(vector<int>& nums) {
   int right=nums.size()-1;
    for(int i=nums.size()-2;i>=0;i--){
        if(i+nums[i]>=right){
            right=i;
        }
    }
    if(right==0)return true;
    return false;
    }
};

45.跳跃游戏II

image

方法一:动态规划 O(n2

dp存到达该点最小步数

class Solution {
public:
    int jump(vector<int>& nums) {
       int dp[10006];
       fill(dp,dp+10006,10006);
       dp[0]=0;
       for(int i=0;i<nums.size()-1;i++){
           //更新从该点能到达的各点
        for(int j=1;j<=nums[i]&&i+j<nums.size();j++){//防止数组越界,所以不能跳出去!
        dp[i+j]=min(dp[i+j],dp[i]+1);
        }
       }
       return dp[nums.size()-1];
    }
    
};

方法二:贪心  (从后往前看能到该点的最前面的点 O(n2))

class Solution {
public:
    int jump(vector<int>& nums) {
        // 贪心思想:要找到距离当前最远的最靠前的点
        int pos = nums.size() - 1;
        int step = 0;
        while (pos > 0) {
            for (int i = 0; i < pos; i++) {
                if (i + nums[i] >= pos) {
                    step++;
                    pos = i;
                    break;
                }
            }
        }
        return step;
    }
};

 

方法三:从前往后 设置一个当前走的步数所能到达的边界

class Solution {
public:
    int jump(vector<int>& nums) {
      int step=0;//跳跃次数
      int maxpos=0;//当前所能跳到最远的距离
      int end=0;//存放当前step下所能到达的最远距离(边界)
      for(int i=0;i<nums.size()-1&&i<=maxpos;i++){
//i<=maxpos这是为了防止可能根本到达不了中间某点,如果中间哪个到不了那一定到不了终点,因为连续跳的。但本题目规定能到终点所以也可以去掉i<=maxpos
          
        maxpos=max(maxpos,i+nums[i]);
        if(i==end){
            step++;
            end=maxpos;
        }
      }
      return step;
    }
    
};

763.划分字母区间

image

class Solution {
public:
    vector<int> partitionLabels(string s) {
        // 贪心:为使片段最多,所以在满足同一个字母一定要出现在同一片段的要求下使得片段越短越好
        // 所以要记录每个字母最后一次出现的位置
        vector<int> v;
        int last[26]; // 每个字母最后出现位置
        for (int i = 0; i < s.size(); i++) {
            last[s[i] - 'a'] = i;
        }
        // 记录当前片段边界
        int start = 0;
        int end = 0;
        for (int i = 0; i < s.size(); i++) {
            end = max(end, last[s[i] - 'a']);
            if (i == end) {
                v.push_back(end - start + 1);
                end = start = i + 1;
            }
        }
        return v;
    }
};

 

posted @ 2025-08-30 11:35  Annaprincess  阅读(6)  评论(0)    收藏  举报