目录
455.分发饼干
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
int size = g.size();
int index = s.size() - 1; // 饼干数组的下标
int result = 0;
sort(g.begin(), g.end());//注意排序!!
sort(s.begin(), s.end());
for(int i = size - 1; i >= 0; i--){//注意:遍历胃口
if(g[i]<=s[index]){
index--;
result++;
}
}
return result;
}
};
我觉得先满足小胃口比较简单:
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int j = 0;
for(int i = 0; i < s.size(); i ++){//fast--s
if(j < g.size() && g[j] <= s[i]) j ++;//slow--g
}
return j;
}
};
376. 摆动序列
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int legth = 1;//ATTENTION : 记录峰值个数,序列默认序列最右边有一个峰值
int curDiff = 0; // 目前差值
int preDiff = 0; // 前一对差值
if(nums.size() <= 2) legth = nums.size();
else{
for(int i = 0; i < nums.size()-1; i++){
curDiff = nums[i+1] - nums[i];
if((preDiff <= 0 && curDiff >0 )|| (preDiff >= 0 && curDiff <0)){
legth++;
preDiff = curDiff;
}
//ATTENTION : 言外之意是,当p<=0 , c <=0时 与 p>=0, c>=0时不更新preDiff
}
}
return legth;
}
};
53. 最大子序和
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int sum = 0;
int res = INT_MIN; //如果这里是0就不对了,那么负数为输出0
for(int i = 0; i < nums.size(); i++){
sum += nums[i];
//这两个顺序还不能反过来,要不还是处理不了-1
res = res > sum ? res : sum;
if(sum <= 0) sum = 0;
}
return res;
}
};
122.买卖股票的最佳时机 II
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<int> diff;
int res = 0;
int size = prices.size();
for(int i = 0; i < size - 1; i++){
if(prices[i+1]-prices[i]>0){
res += prices[i+1]-prices[i];
}
}
return res;
}
};
55.跳跃游戏
class Solution {
public:
bool canJump(vector<int>& nums) {
if(nums.size()==1) return true;
int index = 0;
for(int i = 0; i <= index; i++){//ATTENTION: i<=cover
index = max(index, i + nums[i]);//新添加的cover
if(index >= nums.size()) return true;
}
return false;
}
};
二刷这样做的
class Solution {
public:
bool canJump(vector<int>& nums) {
if(nums.size() == 0) return false;
int right = 0;
for(int i = 0; i < nums.size(); i++){
if(i > right) return false;
right = right > i + nums[i] ? right : i + nums[i];
}
return true;
}
};
45.跳跃游戏 II
class Solution {
public:
int jump(vector<int>& nums) {
int step = 0;
int NextDistance = 0;
int CurrentDistance = 0;
for(int i = 0; i < nums.size(); i++){
NextDistance = max(NextDistance,i + nums[i]);
if(i == CurrentDistance){
step ++;
CurrentDistance = NextDistance;
if(NextDistance >= nums.size()-1) break;
}
}
return step;
}
};
1005.K次取反后最大化的数组和
本题简单一些,估计大家不用想着贪心 ,用自己直觉也会有思路。
关键有二:一个是sort的用法,怎么去定义排序规则;一个是当k没有用完则反转最小的数剩余次数,如果是奇数就是反转一下,如果是偶数就是保持不变。
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
static bool cmp(int a , int b){
return abs(a) > abs(b);//降序
}
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
int res = 0;
sort(nums.begin(), nums.end(), cmp);
for(int i = 0; i < nums.size(); i++){
if(nums[i] < 0 && k > 0){//将最大的负数取反
nums[i] = -nums[i];
k--;
}
}
if( k>0 && k%2==1) nums[nums.size()-1] *= -1;//将最小的值反转一下
for(int n:nums) res += n;
return res;
}
};
134. 加油站
本题有点难度,不太好想,推荐大家熟悉一下方法二
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int size = gas.size();
vector<int> pure(size);
int Cursum = 0;
int CursumMin = INT_MAX;
int index;
for(int i = 0; i < size; i++){
pure[i] = gas[i] - cost[i];
Cursum = Cursum + pure[i];
cout << Cursum << endl;
if(Cursum <= CursumMin){
index = i + 1;//默认标号是0时 cursum = 0; 此后计算时index是标号的后一个数
CursumMin = Cursum;
}
}
if(Cursum >= 0) return index;//此时Cursum就是总和
else return -1;
}
};
135. 分发糖果
本题涉及到一个思想,就是想处理好一边再处理另一边,不要两边想着一起兼顾,后面还会有题目用到这个思路
class Solution {
public:
int candy(vector<int>& ratings) {
int res = 0;
vector<int> candy(ratings.size(), 1);//每个child至少一个糖果
for(int i = 1; i < ratings.size(); i++){
if(ratings[i] > ratings[i - 1]){
candy[i] = candy[i - 1] + 1;
}
}
for(int i = ratings.size() - 2; i >= 0; i--){
if(ratings[i] > ratings[i + 1]){
candy[i] = candy[i + 1] + 1;
}
}
for(int i = 0; i < ratings.size(); i++){
res = res + candy[i];
}
return res;
}
};
860.柠檬水找零
本题看上好像挺难,其实挺简单的。关键是当收到20元时,优先用一张10元和一张5元找开,没有的话再用三张5元找开。
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five = 0, ten = 0, tewlve = 0;
for(int bill:bills){
if(bill == 5){
five ++;
}
if(bill == 10){
if(five > 0){
five --;
ten ++;
}else return false;
}
if(bill == 20){
if(five > 0 && ten > 0){
five --;
ten --;
// tewlve ++;
}
else if(five >= 3){
five -= 3;
// tewlve ++;
}else return false;
}
}
return true;
}
};
406.根据身高重建队列
本题有点难度,和分发糖果类似,不要两头兼顾,处理好一边再处理另一边。
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
private:
static bool cmp(vector<int>& a, vector<int>& b){
return a[0] > b[0];
}
public:
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(),people.end(),cmp);//按照第一个元素排序
vector<vector<int>> que;
for(int i = 0; i < people.size(); i++){
int position = people[i][1];
que.insert(que.begin()+position,people[i]);//ATTENTION
}
return que;
}
};
重叠区间
452. 用最少数量的箭引爆气球
本题是一道 重叠区间的题目,好好做一做,因为明天三道题目,都是 重叠区间。
class Solution {
private:
static bool cmp(vector<int>& a, vector<int>& b){//ATTENTION: vector<int>&
return a[0] < b[0];
}
public:
int findMinArrowShots(vector<vector<int>>& points) {
if(points.size() == 0) return 0;
int res = 1;//poins不为空,至少需要一支箭
sort(points.begin(),points.end(),cmp);//按第一个元素从小到大排序
for(int i = 1; i < points.size(); i++){
if(points[i-1][1] < points[i][0]) res++;//需要一支箭
else{
points[i][1] = min(points[i][1], points[i-1][1]);//更新最小右边界(这里如果新开一个变量会不太方便)
}
}
return res;
}
};
二刷写的
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
sort(points.begin(), points.end(), cmp);
if (points.size() == 0) return 0;
int right = INT_MAX;
int res = 1;
for(int i = 1; i < points.size() ; i++){
right = min(right, points[i - 1][1]);
if(right < points[i][0]){
res ++;
right = points[i][1];
}
}
return res;
}
static bool cmp(vector<int> a, vector<int> b){
return a[0] < b[0];
}
};
435. 无重叠区间
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
private:
static bool cmp(vector<int>& a, vector<int>& b){
return a[0] < b[0];
}
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
int res = 0;
sort(intervals.begin(), intervals.end(), cmp);
for(int i = 1; i < intervals.size(); i++){
if(intervals[i-1][1] > intervals[i][0]) {
res++;
intervals[i][1] = min(intervals[i][1], intervals[i-1][1]);
}
}
return res;
}
};
763.划分字母区间
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
vector<int> partitionLabels(string s) {
int hash[27]={0};
vector<int> res;
for(int i = 0; i < s.size(); i++){
hash[s[i] - 'a'] = i;//覆盖,最终保存最远距离
}
// cout << hash[0] <<endl;
int left = 0;
int right= 0;
for(int i = 0; i < s.size(); i++){
right = max(right, hash[s[i] - 'a']);
if(right == i){
res.push_back(right - left + 1);
left = i + 1;
}
}
return res;
}
};
56. 合并区间
本题相对来说就比较难了。
代码随想录
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> res;
if (intervals.size() == 0) return result; // 区间集合为空直接返回
// 排序的参数使用了lambda表达式
sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b){return a[0] < b[0];});
res.push_back(intervals[0]);
for(int i = 0; i < intervals.size(); i++){
if(res.back()[1] >= intervals[i][0]){
res.back()[1] = max(res.back()[1], intervals[i][1]);
}else{
res.push_back(intervals[i]);
}
}
return res;
}
};
我的二刷:
我用了个slow指针控制新向量的移动速度,方便索引vec[slow][1],代码随想录里面用的vec.back()[1]来索引这个值,也成。
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(), cmp);
vector<vector<int>> vec;
if(intervals.size() == 0) return intervals;
vec.push_back(intervals[0]);
int slow = 0;
for(int i = 1; i < intervals.size(); i++){
if(vec[slow][1] >= intervals[i][0]){
vec[slow][1] = max(vec[slow][1], intervals[i][1]);
}else{
vec.push_back(intervals[i]);
slow++;
}
}
return vec;
}
static bool cmp(vector<int> a, vector<int> b){
return a[0] < b[0] ;
}
};
我的一刷:(可通过)
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
if(intervals.size() < 2) return intervals;
sort(intervals.begin(), intervals.end(),cmp);
vector<vector<int>> outElement;
int element2 = intervals[0][1];
int element1 = intervals[0][0];
for(int i = 1; i < intervals.size(); i++){
cout << element2 << '*' << intervals[i][0] <<endl;
if(element2 >= intervals[i][0]){
element2 = max(element2, intervals[i][1]);
}else{
outElement.push_back({element1, element2});
element1 = intervals[i][0];
element2 = intervals[i][1];
}
}
outElement.push_back({element1,element2});
return outElement;
}
static bool cmp(vector<int> a, vector<int> b){
return a[0] < b[0];
}
};
738.单调递增的数字
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string strNum = to_string(n);
int flag9 = strNum.size();
for(int i = strNum.size()-1; i > 0; i--){
if(strNum[i-1] > strNum[i]){
strNum[i-1]--;
flag9 = i;
}
}
for(int i = flag9; i < strNum.size(); i++){
strNum[i] ='9';//ATTENTION:''
}
return stoi(strNum);
}
};
968.监控二叉树 (可以跳过)
本题是贪心和二叉树的一个结合,比较难,一刷大家就跳过吧。
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
总结
可以看看贪心算法的总结,贪心本来就没啥规律,能写出个总结篇真的不容易了。