前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >贪心算法总结(4)

贪心算法总结(4)

作者头像
小陈在拼命
发布2024-08-21 14:15:43
800
发布2024-08-21 14:15:43
举报
文章被收录于专栏:C/C++、数据结构、算法

一、跳跃游戏I

55. 跳跃游戏 - 力扣(LeetCode)

代码语言:javascript
复制
class Solution {
public:
    bool canJump(vector<int>& nums) {
          //贪心+双指针   用left和right指向两个区间 然后maxpos表示下一层的最右端点
        int left=0,right=0,maxpos=0,n=nums.size();
        while(left<=right) //有可能会跳不到n-1的位置 比如说出现了很多个0
        {
            if(maxpos>=n-1) return true;
            for(int i=left;i<=right;++i) maxpos=max(maxpos,nums[i]+i);
            //找到之后更新区间
            left=right+1;
            right=maxpos;
        }
        return false;
    }
};

二、跳跃游戏II

45. 跳跃游戏 II - 力扣(LeetCode)

解法1 :动态规划

代码语言:javascript
复制
class Solution {
public:
    int jump(vector<int>& nums) {
   //动态规划的思想 dp[i]表示以i位置为结尾时的最小步数
       int n=nums.size();
       vector<int> dp(n,INT_MAX);
       dp[0]=0;
       for(int i=1;i<n;++i)
         for(int j=0;j<i;++j)
          if(nums[j]+j>=i) dp[i]=min(dp[i],dp[j]+1);
        return dp[n-1];
    }
};

解法2:贪心 +双指针

代码语言:javascript
复制
class Solution {
public:
    int jump(vector<int>& nums) {
        //贪心+双指针   用left和right指向两个区间 然后maxpos表示下一层的最右端点
        int left=0,right=0,maxpos=0,ret=0,n=nums.size();
        while(left<=right) //有可能会跳不到n-1的位置 比如说出现了很多个0
        {
            if(maxpos>=n-1) return ret;
            for(int i=left;i<=right;++i) maxpos=max(maxpos,nums[i]+i);
            //找到之后更新区间
            left=right+1;
            right=maxpos;
            ++ret;
        }
        return -1;
    }
};

三、加油站

134. 加油站 - 力扣(LeetCode)

四、距离相等的条形码

1054. 距离相等的条形码 - 力扣(LeetCode)

代码语言:javascript
复制
class Solution {
public:
    vector<int> rearrangeBarcodes(vector<int>& nums) {
      //贪心  隔一个放一个 要顺便统计最多的那个
      int n=nums.size();
      unordered_map<int,int> hash;
      int maxval=0,maxcount=0;
      for(auto&e:nums)
        if(maxcount<++hash[e])
        {
            maxcount=hash[e];
            maxval=e;
        }
      //开始先放最大的数
      vector<int> ret(n);
      int index=0;
      for(int i=0;i<maxcount;++i)
      {
         ret[index]=maxval;
         index+=2;
      }
      hash.erase(maxval);
      //开始放后面的数字
      for(auto&[x,y]:hash)
         for(int i=0;i<y;++i)
         {
            if(index>=n) index=1;
            ret[index]=x;
            index+=2;
         }
      return ret;
    }
};

五、合并区间

56. 合并区间 - 力扣(LeetCode)

代码语言:javascript
复制
class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& nums) {
       //区间问题  按照左端点排序
       sort(nums.begin(),nums.end());
       int n=nums.size();
       //合并区间
       //用left和right来标记两个区间
       //如果left right     a   b   如果重叠了a<=right right=max(right,b)
                                    //如果没有重叠 将left和right丢到ret中  然后更新
        int left=nums[0][0],right=nums[0][1];
        vector<vector<int>> ret;
        for(int i=1;i<n;++i)
        {
            int a=nums[i][0],b=nums[i][1];
            if(a<=right) right=max(right,b);
            else 
            {
              ret.push_back({left,right});
              left=a,right=b;
            }
        }
        ret.push_back({left,right});
        return ret;
    }
};

六、无重叠区间

435. 无重叠区间 - 力扣(LeetCode)

代码语言:javascript
复制
class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& nums) {
        sort(nums.begin(),nums.end());
        int n=nums.size();
        int ret=0;
        int left=nums[0][0],right=nums[0][1];
        for(int i=1;i<n;++i)
        {
            int a=nums[i][0],b=nums[i][1];
            if(a<right) 
            {
                right=min(right,b);
                ++ret;
            } //移除右端点较大的区间  更新右区间
            else right=b;
        }
        return ret;
    }
};

七、用最少数量的箭引爆气球

452. 用最少数量的箭引爆气球 - 力扣(LeetCode)

代码语言:javascript
复制
class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& nums) {
      //只要出现重叠区间,就可以用一只箭射穿
      sort(nums.begin(),nums.end());
      int n =nums.size();
      int left=nums[0][0],right=nums[0][1]; //保留的是交集
      int ret=1;
      for(int i=1;i<n;++i)
      {
        int a=nums[i][0],b=nums[i][1];
        if(a<=right)//如果有交集 
        {
          right=min(right,b);
        }
        else //说明没有交集
        {
            right=b;
            ++ret;
        }
      }
      return ret;
    }
};

八、俄罗斯套娃信封问题

354. 俄罗斯套娃信封问题 - 力扣(LeetCode)

代码语言:javascript
复制
class Solution {
public:
    int maxEnvelopes(vector<vector<int>>& e) {
       //重写排序+贪心+二分
       int n=e.size();
       sort(e.begin(),e.end(),[&e](const vector<int>&v1, const vector<int>&v2){
             return v1[0]!=v2[0]?v1[0]<v2[0]:v1[1]>v2[1];
       });
       vector<int> ret;
       ret.emplace_back(e[0][1]);
       for(int i=1;i<n;++i)
       {
          int b=e[i][1];
         //如果我比最后一个都大 我直接尾插
         if(b>ret.back()) ret.emplace_back(b);
         else //否则就二分
         {
             int left=0,right=ret.size()-1;
             while(left<right)
             {
               int mid=(left+right)>>1;
               if(ret[mid]<b) left=mid+1;
               else right=mid;
             }
             ret[left]=b;
         }
       }
       return ret.size();
    }
};

九、堆箱子

面试题 08.13. 堆箱子 - 力扣(LeetCode)

代码语言:javascript
复制
class Solution {
public:
    int pileBox(vector<vector<int>>& nums) {
       sort(nums.begin(),nums.end());
       int n=nums.size();
       //23 54 64 67
       //dp[i]表示以i位置为结尾的最长递增子序列的长度
       vector<int> dp(n);
       for(int i=0;i<n;++i) dp[i]=nums[i][2];
       for(int i=1;i<n;++i)
          //开始往前找
          for(int j=0;j<i;++j) 
          if(nums[i][0]>nums[j][0]&&nums[i][1]>nums[j][1]&&nums[i][2]>nums[j][2])
           dp[i]=max(dp[i],dp[j]+nums[i][2]);
        return *max_element(dp.begin(),dp.end()); 
    }
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、跳跃游戏I
  • 二、跳跃游戏II
  • 三、加油站
  • 四、距离相等的条形码
  • 五、合并区间
  • 六、无重叠区间
  • 七、用最少数量的箭引爆气球
  • 八、俄罗斯套娃信封问题
  • 九、堆箱子
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档