当前位置:   article > 正文

贪心算法总结(4)

贪心算法总结(4)

一、跳跃游戏I

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

  1. class Solution {
  2. public:
  3. bool canJump(vector<int>& nums) {
  4. //贪心+双指针 用left和right指向两个区间 然后maxpos表示下一层的最右端点
  5. int left=0,right=0,maxpos=0,n=nums.size();
  6. while(left<=right) //有可能会跳不到n-1的位置 比如说出现了很多个0
  7. {
  8. if(maxpos>=n-1) return true;
  9. for(int i=left;i<=right;++i) maxpos=max(maxpos,nums[i]+i);
  10. //找到之后更新区间
  11. left=right+1;
  12. right=maxpos;
  13. }
  14. return false;
  15. }
  16. };

二、跳跃游戏II

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

 解法1 :动态规划

  1. class Solution {
  2. public:
  3. int jump(vector<int>& nums) {
  4. //动态规划的思想 dp[i]表示以i位置为结尾时的最小步数
  5. int n=nums.size();
  6. vector<int> dp(n,INT_MAX);
  7. dp[0]=0;
  8. for(int i=1;i<n;++i)
  9. for(int j=0;j<i;++j)
  10. if(nums[j]+j>=i) dp[i]=min(dp[i],dp[j]+1);
  11. return dp[n-1];
  12. }
  13. };

解法2:贪心 +双指针

  1. class Solution {
  2. public:
  3. int jump(vector<int>& nums) {
  4. //贪心+双指针 用left和right指向两个区间 然后maxpos表示下一层的最右端点
  5. int left=0,right=0,maxpos=0,ret=0,n=nums.size();
  6. while(left<=right) //有可能会跳不到n-1的位置 比如说出现了很多个0
  7. {
  8. if(maxpos>=n-1) return ret;
  9. for(int i=left;i<=right;++i) maxpos=max(maxpos,nums[i]+i);
  10. //找到之后更新区间
  11. left=right+1;
  12. right=maxpos;
  13. ++ret;
  14. }
  15. return -1;
  16. }
  17. };

三、加油站

134. 加油站 - 力扣(LeetCode)

四、距离相等的条形码

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

  1. class Solution {
  2. public:
  3. vector<int> rearrangeBarcodes(vector<int>& nums) {
  4. //贪心 隔一个放一个 要顺便统计最多的那个
  5. int n=nums.size();
  6. unordered_map<int,int> hash;
  7. int maxval=0,maxcount=0;
  8. for(auto&e:nums)
  9. if(maxcount<++hash[e])
  10. {
  11. maxcount=hash[e];
  12. maxval=e;
  13. }
  14. //开始先放最大的数
  15. vector<int> ret(n);
  16. int index=0;
  17. for(int i=0;i<maxcount;++i)
  18. {
  19. ret[index]=maxval;
  20. index+=2;
  21. }
  22. hash.erase(maxval);
  23. //开始放后面的数字
  24. for(auto&[x,y]:hash)
  25. for(int i=0;i<y;++i)
  26. {
  27. if(index>=n) index=1;
  28. ret[index]=x;
  29. index+=2;
  30. }
  31. return ret;
  32. }
  33. };

五、合并区间

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

  1. class Solution {
  2. public:
  3. vector<vector<int>> merge(vector<vector<int>>& nums) {
  4. //区间问题 按照左端点排序
  5. sort(nums.begin(),nums.end());
  6. int n=nums.size();
  7. //合并区间
  8. //用left和right来标记两个区间
  9. //如果left right a b 如果重叠了a<=right right=max(right,b)
  10. //如果没有重叠 将left和right丢到ret中 然后更新
  11. int left=nums[0][0],right=nums[0][1];
  12. vector<vector<int>> ret;
  13. for(int i=1;i<n;++i)
  14. {
  15. int a=nums[i][0],b=nums[i][1];
  16. if(a<=right) right=max(right,b);
  17. else
  18. {
  19. ret.push_back({left,right});
  20. left=a,right=b;
  21. }
  22. }
  23. ret.push_back({left,right});
  24. return ret;
  25. }
  26. };

六、无重叠区间

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

  1. class Solution {
  2. public:
  3. int eraseOverlapIntervals(vector<vector<int>>& nums) {
  4. sort(nums.begin(),nums.end());
  5. int n=nums.size();
  6. int ret=0;
  7. int left=nums[0][0],right=nums[0][1];
  8. for(int i=1;i<n;++i)
  9. {
  10. int a=nums[i][0],b=nums[i][1];
  11. if(a<right)
  12. {
  13. right=min(right,b);
  14. ++ret;
  15. } //移除右端点较大的区间 更新右区间
  16. else right=b;
  17. }
  18. return ret;
  19. }
  20. };

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

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

  1. class Solution {
  2. public:
  3. int findMinArrowShots(vector<vector<int>>& nums) {
  4. //只要出现重叠区间,就可以用一只箭射穿
  5. sort(nums.begin(),nums.end());
  6. int n =nums.size();
  7. int left=nums[0][0],right=nums[0][1]; //保留的是交集
  8. int ret=1;
  9. for(int i=1;i<n;++i)
  10. {
  11. int a=nums[i][0],b=nums[i][1];
  12. if(a<=right)//如果有交集
  13. {
  14. right=min(right,b);
  15. }
  16. else //说明没有交集
  17. {
  18. right=b;
  19. ++ret;
  20. }
  21. }
  22. return ret;
  23. }
  24. };

八、俄罗斯套娃信封问题

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

  1. class Solution {
  2. public:
  3. int maxEnvelopes(vector<vector<int>>& e) {
  4. //重写排序+贪心+二分
  5. int n=e.size();
  6. sort(e.begin(),e.end(),[&e](const vector<int>&v1, const vector<int>&v2){
  7. return v1[0]!=v2[0]?v1[0]<v2[0]:v1[1]>v2[1];
  8. });
  9. vector<int> ret;
  10. ret.emplace_back(e[0][1]);
  11. for(int i=1;i<n;++i)
  12. {
  13. int b=e[i][1];
  14. //如果我比最后一个都大 我直接尾插
  15. if(b>ret.back()) ret.emplace_back(b);
  16. else //否则就二分
  17. {
  18. int left=0,right=ret.size()-1;
  19. while(left<right)
  20. {
  21. int mid=(left+right)>>1;
  22. if(ret[mid]<b) left=mid+1;
  23. else right=mid;
  24. }
  25. ret[left]=b;
  26. }
  27. }
  28. return ret.size();
  29. }
  30. };

九、堆箱子

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

  1. class Solution {
  2. public:
  3. int pileBox(vector<vector<int>>& nums) {
  4. sort(nums.begin(),nums.end());
  5. int n=nums.size();
  6. //23 54 64 67
  7. //dp[i]表示以i位置为结尾的最长递增子序列的长度
  8. vector<int> dp(n);
  9. for(int i=0;i<n;++i) dp[i]=nums[i][2];
  10. for(int i=1;i<n;++i)
  11. //开始往前找
  12. for(int j=0;j<i;++j)
  13. if(nums[i][0]>nums[j][0]&&nums[i][1]>nums[j][1]&&nums[i][2]>nums[j][2])
  14. dp[i]=max(dp[i],dp[j]+nums[i][2]);
  15. return *max_element(dp.begin(),dp.end());
  16. }
  17. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/998501
推荐阅读
相关标签
  

闽ICP备14008679号