贪心法

拆解为子问题最优

局部最优导致全局最优

严格证明可行:数学归纳法,反证法证明贪心可行,一般举反例就行

 排序!!!

举简单例子,看看怎么解,能不能推导出一般解法,也就是局部推整体

455. 分发饼干 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int findContentChildren(vector<int>& g, vector<int>& s) {
 4         sort(g.begin(),g.end());
 5         sort(s.begin(),s.end());
 6         int num = 0;
 7         for(int i=0,j=0;i<g.size()&&j<s.size();i++,j++){
 8             if(g[i]<=s[j])
 9                 num++;
10             else 
11                 i--;
12         }
13         return num;
14     }
15 };
View Code

 376. 摆动序列 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int wiggleMaxLength(vector<int>& nums) {//初始化难
 4         if(nums.size()==0)
 5             return 0;
 6         if(nums.size()==1)
 7             return 1;
 8         int startIndex = 0;
 9         int temp = nums[startIndex]-nums[startIndex+1];
10         while(temp==0&&startIndex+1+1<nums.size()){//找到第一个不为0的差值
11             startIndex++;
12             temp = nums[startIndex]-nums[startIndex+1];
13         }
14         int num = 1;
15         temp*=-1;//自己造一个temp,找到第一个不为0的差值,取他相反数
16         for(int i=startIndex;i+1<nums.size();i++){
17             if(temp*( nums[i]-nums[i+1])>=0)//逻辑前后就是乘机应当<0
18                 continue;
19             temp =  nums[i]-nums[i+1];
20             num++;
21 
22         }
23         return  num;
24     }
25 };
View Code

 53. 最大子数组和 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int maxSubArray(vector<int>& nums) {
 4         int sum = 0,ans = -1e4;
 5         for(int i=0;i<nums.size();i++){
 6             sum+=nums[i];
 7             ans = max(ans,sum);
 8             if(sum<0)
 9                 sum = 0;
10         }
11         return ans;
12     }
13 };
View Code

 122. 买卖股票的最佳时机 II - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int maxProfit(vector<int>& prices) {//示例一二,共同计算方法,第二天卖就行
 4         int ans = 0;
 5         for(int i=1;i<prices.size();i++){
 6             if(prices[i]-prices[i-1]>0)
 7                 ans+=prices[i]-prices[i-1];
 8         }
 9         return ans;
10     }
11 };
View Code

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

 1 class Solution {
 2 public:
 3     bool canJump(vector<int>& nums) {
 4         int mx = 0;
 5         for(int i=0;i<nums.size()&&i<=mx;i++){
 6              mx = max(mx,nums[i]+i);
 7         }
 8         if(mx>=nums.size()-1)
 9             return true;
10         return false;
11     }
12 };
View Code

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

 1 class Solution {
 2 public:
 3     int jump(vector<int>& nums) {
 4         int mx = 0,mxx = 0;
 5         int ans = 0;
 6         for(int i=0;i<nums.size()&&mx<nums.size()-1;i++){//位置下标
 7             for(;i<=mx&&mx<nums.size()-1;i++){
 8                 if(mxx<i+nums[i]){
 9                     mxx = max(mxx,i + nums[i]);
10                 }
11             }
12             if(mx<=mxx){
13                 mx = mxx;
14                 ans++;
15             }
16         }
17         return ans;
18     }
19 };
View Code

 134. 加油站 - 力扣(LeetCode) (leetcode-cn.com)

我自己的想法,类似最大连续区间和

**其实我不认为这种方式是贪心算法,因为没有找出局部最优,而是直接从全局最优的角度上思考问题**。

但这种解法又说不出是什么方法,这就是一个从全局角度选取最优解的模拟操作。

 1 class Solution {
 2 public:
 3     int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
 4         int n = cost.size(),nums[100000] = {0};//差值数组
 5         int startindex=-1;//初始化,用于第一位就是大于0,往后sum一直大于0,那么最大连续区间和前一位就是-1
 6         for(int i=0;i<cost.size();i++){
 7            nums[i] = gas[i]-cost[i];
 8         }
 9         int sum = 0;
10         for(int i=0;i<n;i++){//类似连续区间和最大,找到起始坐标的前一位很快,+1就是起始
11             sum+=nums[i];
12             if(sum<0){
13                 sum = 0;
14                 startindex = i;
15             }
16         }
17         //找到起始位置后还得验证是不是能走完
18         sum=0;
19         int size = 0;//结束for循环用
20         for(int i=startindex+1;size<n;i++){
21             sum+=nums[i%n];
22             if(sum<0){
23                 return -1;
24             }
25             size++;
26         }
27         return startindex+1;
28     }
29 };
View Code

 贪心答案

 1 class Solution {
 2 public:
 3     int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
 4         int curSum = 0;
 5         int totalSum = 0;
 6         int start = 0;
 7         for (int i = 0; i < gas.size(); i++) {
 8             curSum += gas[i] - cost[i];
 9             totalSum += gas[i] - cost[i];
10             if (curSum < 0) {   // 当前累加rest[i]和 curSum一旦小于0
11                 start = i + 1;  // 起始位置更新为i+1
12                 curSum = 0;     // curSum从0开始
13             }
14         }
15         if (totalSum < 0) return -1; // 说明怎么走都不可能跑一圈了
16         return start;
17     }
18 };
View Code

 135. 分发糖果 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int candy(vector<int>& ratings) {
 4         vector<int>ans(20000,1);
 5         int sum = 0;
 6         for(int i=0;i<ratings.size();i++){
 7             if(i-1>=0&&ratings[i]>ratings[i-1]){
 8                 ans[i] = max(ans[i],ans[i-1]+1);
 9             }
10         }
11         for(int i=ratings.size()-1;i>=0;i--){
12             if(i+1<ratings.size()&&ratings[i]>ratings[i+1]){
13                 ans[i] = max(ans[i],ans[i+1]+1);
14             }
15         }
16         for(int i=0;i<ratings.size();i++)
17             sum+=ans[i];
18         return sum;
19     }
20 };
View Code

 860. 柠檬水找零 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     bool lemonadeChange(vector<int>& bills) {
 4         vector<int> a(21,0);
 5         for(int i=0;i<bills.size();i++){
 6             if(bills[i]==5)
 7                 a[5]++;
 8             else if(bills[i]==10){
 9                 if(a[5]==0)
10                     return false;
11                 a[5]--;
12                 a[10]++;
13             }else if(bills[i]==20){
14                 if(a[10]>=1&&a[5]>=1){
15                     a[10]--;
16                     a[5]--;
17                     a[20]++;
18                 }else if(a[5]>=3){
19                     a[5]-=3;
20                     a[20]++;
21                 }else
22                     return false;
23             }
24                 
25         }
26         return true;
27     }
28 };
View Code

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

 1 class Solution {// static bool cmp(const vector<int>& a, const vector<int>& b) {return a[0] < b[0]; }
 2 public:
 3     int findMinArrowShots(vector<vector<int>>& points) {//思路混乱,化整体为局部,就看第一个先。无序的一定排序看看
 4         sort(points.begin(),points.end());//排序啊我是傻逼
 5         int ans = 0;
 6         long long end = -2147489999;
 7         for(int i=0;i<points.size();i++){
 8             if(end>=points[i][0]){
 9                 end = min(end,(long long)points[i][1]);
10             }else {
11                 end = points[i][1];
12                 ans++;
13             }
14         }
15         return ans;
16     }
17 };
View Code

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

 1 class Solution {
 2 public:
 3     vector<vector<int>> merge(vector<vector<int>>& intervals) {
 4         vector<vector<int>> ans;
 5         vector<int> path(2);//老忘记加大小
 6         if(intervals.size()==0)
 7             return ans;
 8         sort(intervals.begin(),intervals.end());
 9         path[0] = intervals[0][0];
10         path[1] = intervals[0][1];
11         for(int i=1;i<intervals.size();i++){
12             if(path[1]>=intervals[i][0]){
13                 path[1] = max(path[1],intervals[i][1]);
14             }else{
15                 ans.push_back(path);
16                 path[0] = intervals[i][0];
17                 path[1] = intervals[i][1];
18             }
19         }
20         ans.push_back(path);
21         return ans;
22     }
23 };
View Code

 738. 单调递增的数字 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int monotoneIncreasingDigits(int n) {
 4         string strNum = to_string(n);
 5         int startIndex = strNum.size();
 6         for(int i = strNum.size()-1;i>0;i--){
 7             if(strNum[i-1]>strNum[i]){
 8                 strNum[i-1]--;
 9                 startIndex = i;
10             }
11         }
12         for(int i=startIndex;i<strNum.size();i++){
13             strNum[i] = '9';
14         }
15         return stoi(strNum);
16     }
17 };
View Code

 

posted @ 2022-02-05 13:21  剩下的交给时间就好  阅读(71)  评论(0编辑  收藏  举报