class Solution {public: int findContentChildren(vector<int>& g, vector<int>& s) { //先排序 sort(g.begin(),g.end()); sort(s.begin(),s.end()); //遍历s的index,饼干数组的下标 int index=s.size()-1; //喂饱的小孩数 int result=0; //大饼干喂给胃口大的-->局部最优 for(int i=g.size()-1;i>=0;i--){ //先判断index, 否则若index==0,则 s[index]越界报错 if(index >= 0 && s[index] >= g[i]){ result++; index--; } } return result; }};
//贪心算法class Solution {public: int wiggleMaxLength(vector<int>& nums) { int n=nums.size(); if(n<=1){ return n; } //记录前一差值 int preDiff=0; //记录当前差值 int curDiff=0; // 记录峰值个数,序列默认序列最右边有一个峰值 int result=1; for(int i=0;i<n-1;i++){ curDiff=nums[i+1]-nums[i]; //出现峰值 if(( preDiff>=0 && curDiff<0 ) ||( preDiff<=0 && curDiff>0 ) ){ result++; preDiff=curDiff; } } return result; }};//动态规划class Solution {public: int wiggleMaxLength(vector<int>& nums) { int n=nums.size(); //status and define dp[][0]代表山峰,dp[][1]为山谷。 vector<vector<int>> dp(n,vector<int>(2)); if(n<2){ return n; } //base case dp[0][0]=1; dp[0][1]=1; //transform for(int i=1;i<n;i++){ dp[i][0]=1; dp[i][1]=1; //找山峰 for(int j=0;j<i;j++){ if(nums[i]>nums[j]){ dp[i][0]=max(dp[j][1]+1,dp[i][0]); } } //找山谷 for(int j=0;j<i;j++){ if(nums[i]<nums[j]){ dp[i][1]=max(dp[j][0]+1,dp[i][1]); } } } return max(dp[n-1][0],dp[n-1][1]); }};//另一种动态规划class Solution {public: int wiggleMaxLength(vector<int>& nums) { int n=nums.size(); //status and define dp_up[]代表最后一个为上升的最长序列长度,dp_down[]为最后一个为下降的最长序列长度。 vector<int> dp_up(n),dp_down(n); if(n<2){ return n; } //base case dp_up[0]=1; dp_down[0]=1; //transform for(int i=1;i<n;i++){ if(nums[i]>nums[i-1]){ dp_up[i]=dp_up[i-1]; dp_down[i]=max(dp_down[i-1],dp_up[i-1]+1); }else if(nums[i]<nums[i-1]){ dp_up[i]=max(dp_up[i-1],dp_down[i-1]+1); dp_down[i]=dp_down[i-1]; }else{ dp_up[i]=dp_up[i-1]; dp_down[i]=dp_down[i-1]; } } return max(dp_up[n-1],dp_down[n-1]); }};//另一种动态规划的优化class Solution {public: int wiggleMaxLength(vector<int>& nums) { int n=nums.size(); //status and define dp_up[]代表最后一个为上升的最长序列长度,dp_down[]为最后一个为下降的最长序列长度。 if(n<2){ return n; } //base case int dp_up=1; int dp_down=1; //transform for(int i=1;i<n;i++){ if(nums[i]>nums[i-1]){ // dp_up[i]=dp_up[i-1]; // dp_up=dp_up; // dp_down[i]=max(dp_down[i-1],dp_up[i-1]+1); dp_down=max(dp_down,dp_up+1); }else if(nums[i]<nums[i-1]){ // dp_up[i]=max(dp_up[i-1],dp_down[i-1]+1); dp_up=max(dp_up,dp_down+1); // dp_down=dp_down; // dp_down[i]=dp_down[i-1]; }else{ // dp_up[i]=dp_up[i-1]; // dp_down[i]=dp_down[i-1]; } } return max(dp_up,dp_down); }};
class Solution {public: int maxSubArray(vector<int>& nums) { int n=nums.size(); int result=0; //记录累计结果 int m_max=INT_MIN; //最大和 for(int i=0;i<n;i++){ result+=nums[i]; if(m_max<result){ m_max=result; } if(result<=0){ //结果为负数 重新计数 result=0; } } return m_max; }};
class Solution {
public:
int maxProfit(vector<int>& prices) {
int result=0;
//局部最优,每天的利润最大化
for(int i=1;i<prices.size();i++){
result+=max(prices[i]-prices[i-1],0);
}
return result;
}
};
class Solution {
public:
bool canJump(vector<int>& nums) {
//跳跃可覆盖的最大距离到终点时为整体最优,每个位置跳跃最大距离为局部最优
int cover=0; //当前下标
//只有1个元素时,肯定可达
if(nums.size()==1){
return true;
}
for(int i=0;i<=cover;i++){
//max(此位置上可覆盖的最大距离,之前的cover)
cover=max(nums[i]+i,cover);
//可以覆盖
if(cover>=nums.size()-1){
return true;
}
}
return false;
}
};
class Solution {
public:
int jump(vector<int>& nums) {
//局部最优:每次走最远
if(nums.size()==1){
return 0;
}
int step=0;
for(int i=0;i<nums.size();i++){
//在此位置最大覆盖距离可以到达最后一个位置
if(i+nums[i]>=nums.size()-1){
step++;
return step;
}
//不能到达时
//记录每个元素跳跃后可再次可跳跃的最大位置
int pos_max=0;
//记录此次跳跃步数下标
int pos=i+1;
for(int j=i+1;j<i+1+nums[i];j++){
//找跳跃到下一个格子的最大距离
if(j+nums[j]>=pos_max){
pos_max=j+nums[j];
//下标减1
pos=j-1;
}
}
i=pos;
step++;
}
return step;
}
};
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(k>0&&nums[i]<0){
nums[i]=-nums[i];
k--;
}
}
//K还没用完,反复转换最后一个负数
if(k%2==1) nums[nums.size()-1]*=-1;
return accumulate(nums.begin(),nums.end(),0);
}
};
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
//先看总油量和总耗量
int sum=0;
//油箱剩余的油最小值
int min_rest=INT_MAX;
for(int i=0;i<gas.size();i++){
sum+=gas[i]-cost[i];
min_rest=min(sum,min_rest);
}
//总油量<总耗量,不可能跑完
if(sum<0){
return -1;
}
//油箱剩余的油每次都够,从0出发就可以
if(min_rest>=0){
return 0;
}
//都不行,那就先找油,找最先让油箱有min_rest的油,要从后往前找
for(int i=gas.size()-1;i>=0;i--){
min_rest+=gas[i]-cost[i];
if(min_rest>=0){
return i;
}
}
return -1;
}
};
//第二种贪心
//局部最优:当前累加rest[j]的和curSum一旦小于0,起始位置至少要是j+1,因为从j开始一定不行。
//全局最优:找到可以跑一圈的起始位置。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int start=0;
int today_sum=0;
int sum=0;
for(int i=0;i<gas.size();i++){
today_sum+=gas[i]-cost[i];
sum+=gas[i]-cost[i];
//第i天出现负油量,重新开始计算,从i+1开始
if(today_sum<0){
start=i+1;
today_sum=0;
}
}
if(sum<0){
return -1;
}
return start;
}
};
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string strNum=to_string(n);
int flag=strNum.size();
for(int i=strNum.size()-1;i>0;i--){
if(strNum[i]<strNum[i-1]){
strNum[i-1]--;
flag=i;
}
}
for(int i=flag;i<strNum.size();i++){
strNum[i]='9';
}
return stoi(strNum);
}
};