2021-09-24 贪心算法

贪心

分发饼干
class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
		sort(g.begin(),g.end());
		sort(s.begin(),s.end());
		int index=s.size()-1;
		int res=0;
		for(int i=g.size()-1;i>=0;i--){//循环到小孩胃口结束
			if(index>=0 && s[index]>=g[i]){
				index--;//配对后饼干大小向前进,结果加1
				res++;
			}
		}
		return res;
    }
};
摆动序列
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
		if(nums.size()<=1) return nums.size();
		int curDiff=0;
		int preDiff=0;
		int res=1;
		for(int i=1;i<nums.size();i++){
			curDiff=nums[i]-nums[i-1];
			if((curDiff>0 && preDiff<=0)||(curDiff<0 && preDiff>=0)){
				res++;
				preDiff =curDiff;
			}			
		}
		return res;
    }
};
最大子序和
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
		int res=INT_MIN;
		int count=0;
		for(int i=0;i<nums.size();i++){
			count+=nums[i];
			if(count>res) res=count;
			if(count<0) count=0;
		}
		return res;
    }
};
买卖股票的最佳时机 II
class Solution {
public:
    int maxProfit(vector<int>& prices) {
		int res=0;
		for(int i=1;i<prices.size();i++){
			res+=max(prices[i]-prices[i-1],0);
		}
		return res;
    }
};
跳跃游戏
class Solution {
public:
    bool canJump(vector<int>& nums) {
		int cover=0;
		if(nums.size()==1) return 1;
		for(int i=0;i<=cover;i++){//!!<=
			cover=max(i+nums[i],cover);
			if(cover>=nums.size()-1) return 1;
		}
		return 0;
    }
};
跳跃游戏 II
class Solution {
public:
    int jump(vector<int>& nums) {
		int curDistance=0;
		int nextDistance=0;
		int ans=0;
		for(int i=0;i<nums.size()-1;i++){
			nextDistance=max(i+nums[i],nextDistance);
			if(i==curDistance){
				curDistance=nextDistance;
				ans++;
			}
		}
		return ans;

    }
};
K 次取反后最大化的数组和
class Solution {
public:
	static bool cmp(int a,int b){
		return abs(a)>abs(b);
	}
    int largestSumAfterKNegations(vector<int>& nums, int k) {
		sort(nums.begin(),nums.end(),cmp);//按绝对值大到小排序
		for(int i=0;i<nums.size();i++){
			if(nums[i]<0 && k>0){//若k>0,按顺序把最小的负数取反
				nums[i]*=-1;
				k--;
			}
		}
		while(k--){//若负数取反后k仍大于0,对绝对值最小的正数不断取反
			nums[nums.size()-1]*=-1;
		}
		int res=0;
		for(int num:nums){
			res+=num;
		} 
		return res;
    }
};
加油站

[i,j] 区间和为负数,起始位置就可以是j+1

因为j之前出现了多少负数,j后面就会出现多少正数,因为耗油总和是大于零的(前提我们已经确定了一定可以跑完全程)

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
		int curRest=0;//目前剩余量
		int totalR=0;//总剩余量
		int start=0;
		for(int i=0;i<gas.size();i++){
			curRest+=gas[i]-cost[i];
			totalR+=gas[i]-cost[i];
			if(curRest<0){
				start=i+1;
				curRest=0;
			}
		}
		if(totalR<0) return -1;//走不完一圈
    	return start;
	}
};
分发糖果
class Solution {
public:
    int candy(vector<int>& ratings) {
		vector<int> candys(ratings.size(),1);
		for(int i=1;i<ratings.size();i++){
			if(ratings[i]>ratings[i-1]){
				candys[i]=candys[i-1]+1;
			}
		}
		for(int i=ratings.size()-2;i>=0;i--){
			if(ratings[i]>ratings[i+1]){
				candys[i]=max(candys[i],candys[i+1]+1);
			}
		}
		int res=0;
		for(int i=0;i<candys.size();i++){
			res+=candys[i];
		}
		return res;
    }
};
柠檬水找零
class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
		int five=0,ten=0;//不需要记录20元,因为不需要用20元找0
		for(int bill:bills){
			if(bill==5){
				five++;
			}
			if(bill==10){
				if(five<=0){
					return 0;
				}
				else{
					ten++;
					five--;
				}
			}
			if(bill==20){
				if(five>0&&ten>0){
					five--;
					ten--;
				}
				else if(five>=3){
					five-=3;
				}
				else return 0;
			}
		}
		return 1;
    }
};
根据身高重建队列

static https://blog.csdn.net/qq_26849233/article/details/77930991

class Solution {
public:
	static bool cmp(vector<int> a,vector<int> b){//定义为static成员函数
		if(a[0]==b[0]) return a[1]<b[1];
		return a[0]>b[0];
	}
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
		sort(people.begin(),people.end(),cmp);
		vector<vector<int>> res;
		for(int i=0;i<people.size();i++){
			int position=people[i][1];
			res.insert(res.begin()+position,people[i]);
		}
		return res;
    }
};
用最少数量的箭引爆气球
class Solution {
public:
	static bool cmp(vector<int>& a,vector<int>& b){
		return a[0]<b[0];
	} 
    int findMinArrowShots(vector<vector<int>>& points) {
		if (points.empty()) {
            return 0;
        }
        sort(points.begin(),points.end(),cmp);
		int res=1;
		for(int i=1;i<points.size();i++){
			if(points[i][0]>points[i-1][1]){
				res++;
			}
			else{//重叠,更新右边界,取最小值 
				points[i][1]=min(points[i-1][1],points[i][1]);
			}
		}
		return res;		
    }
};
无重叠区间
class Solution {
public:
    static bool cmp(vector<int>& a,vector<int>& b){
    	return a[1]<b[1];//按右边界小到大排序
	}
	int eraseOverlapIntervals(vector<vector<int>>& intervals) {
		if(intervals.empty()) return 0;
		sort(intervals.begin(),intervals.end(),cmp);
		int count=1;
		int end=intervals[0][1];
		for(int i=1;i<intervals.size();i++){
			if(end<=intervals[i][0]){//计数非交叉区间个数
				end=intervals[i][1];
				count++;
			}
		}
		return intervals.size()-count;
    }
};
划分字母区间
class Solution {
public:
    vector<int> partitionLabels(string s) {
		int hash[27]={0};
		for(int i=0;i<s.size();i++){
			hash[s[i]-'a']=i;
		}
		vector<int> res;
		int l=0,r=0;
		for(int i=0;i<s.size();i++){
			r=max(r,hash[s[i]-'a']);
			if(i==r){
				res.push_back(r-l+1);
				l=i+1;
			}
		}
		return res;
    }
};
合并区间

lambda表达式???

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        vector<vector<int>> res;
        if(intervals.size()==0) return res;
        sort(intervals.begin(),intervals.end(),[](vector<int>& a,vector<int>& b){
			return a[0]<b[0];
		});//左边界排序
		res.push_back(intervals[0]);
		for(int i=1;i<intervals.size();i++){
			if(res.back()[1]>=intervals[i][0]){//在res内合并
				res.back()[1]=max(res.back()[1],intervals[i][1]);			
			}
			else{
				res.push_back(intervals[i]);
			}
		}
		return res;
    }
};
单调递增的数字

332->222->299

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
		string num=to_string(n);//int to string
		int flag=num.size();//标志遍历9的起始位置,并防止第二个循环在没赋值情况下执行
		for(int i=num.size()-1;i>0;i--){
			if(num[i-1]>num[i]){
				flag=i;
				num[i-1]--;
			}
		}
		for(int i=flag;i<num.size();i++){
			num[i]='9';
		}
		return stoi(num);//string to int
    }
};
买卖股票的最佳时机含手续费
class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
		int res=0;
		int buy=prices[0];
		for(int i=1;i<prices.size();i++){
			if(prices[i]<buy){//相当于买入,可以是多次(同样也相当于卖出)
				buy=prices[i];
			}
			if(prices[i]>buy+fee){
				res+=prices[i]-(buy+fee);
				buy=prices[i]-fee;//若未卖出,则不需要再次减手续费,本次已经减了 
			} 
		}
		return res; 
    }
};
监控二叉树
class Solution {
public:
    int res=0;
	int traversal(TreeNode* cur){
		if(cur==NULL){//终止条件空结点,状态为有覆盖符合父结点放置摄像头规则,无实际意义
			return 2;
		}
		int l=traversal(cur->left);
		int r=traversal(cur->right);
		if(l==2&&r==2){//左右结点都是有覆盖即父结点无覆盖 
			return 0;
		}
		if(l==0||r==0){//左右节点至少一个无覆盖 
			res++; 
			return 1;
		}
		if(l==1||r==1){//左右结点至少有一个摄像头,或者都有 
			return 2;
		}
        return -1;
	}
    int minCameraCover(TreeNode* root) {
		if(traversal(root)==0){
			res++;
		}
		return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值