一个本硕双非的小菜鸡,备战24年秋招,计划刷完卡子哥的刷题计划,加油!
推荐一手卡子哥的刷题网站,感谢卡子哥。代码随想录
贪心:通过局部最优,推出整体最优。
455. 分发饼干
Note:贪心第一题,思路很简单。但是要注意if循环先判断sSize >= 0,要不然会内存泄漏。
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int gSize = g.size() - 1;
int sSize = s.size() - 1;
int result = 0;
for (int i = gSize; i >= 0; i--) {
if (sSize >= 0 && g[i] <= s[sSize]) {
result++;
sSize--;
}
}
return result;
}
};
376. 摆动序列
Note:这道题跟我之前周赛的题目有点像,可惜当时没做出来
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
int curDiff = 0; //当前差值
int preDiff = 0; //前一对差值
int result = 1;
for (int i = 0; i < nums.size() - 1; i++) {
curDiff = nums[i + 1] - nums[i];
if ((preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)) {
result++;
preDiff = curDiff;
}
}
return result;
}
};
53. 最大子数组和
Note:不难,我感觉我好像做过类似的
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int res = INT32_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;
}
};
122. 买卖股票的最佳时机 II
Note:…原来做过类似的是这道题
class Solution {
public:
int maxProfit(vector<int>& prices) {
int res = 0;
for (int i = 1; i < prices.size(); i++) {
if (prices[i] - prices[i - 1] > 0)
res += prices[i] - prices[i - 1];
}
return res;
}
};
55. 跳跃游戏
Note:贪心想法很简单,是我想麻烦了
class Solution {
public:
bool canJump(vector<int>& nums) {
int cover = 0;
if (nums.size() == 1) return true;
for (int i = 0; i <= cover; i++) {
cover = max(cover, i + nums[i]);
if (cover >= nums.size() - 1) return true;
}
return false;
}
};
45. 跳跃游戏 II
Note:我真想到强化就是找最短路径
class Solution {
public:
int jump(vector<int>& nums) {
if (nums.size() == 1) return 0;
int curDistance = 0; //当前最远可到达的位置
int res = 0;
int nextDistance = 0; //下一步最远可到达的位置
for (int i = 0; i < nums.size(); i++) {
nextDistance = max(nums[i] + i, nextDistance);
if (i == curDistance) {
res++;
curDistance = nextDistance;
if (nextDistance >= nums.size() - 1) break;
}
}
return res;
}
};
1005. K 次取反后最大化的数组和
Note:思路很好想,先排序再顺序翻转的负数
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] = abs(nums[i]);
k--;
}
}
if (k % 2 == 1) nums[nums.size() - 1] *= -1;
for (int a : nums) res += a;
return res;
}
};
78. 子集
Note:并不是代码随想录中的一题,是每日一题遇到的。贪心算法帮助我搞定了第一道困难。
此处采用了题解中Ikaruga大佬的优化解答
思路
1.贪心
2.越往后乘积越大,越大的数应该放在最后,所以先排个序
3.从后面一个一个加入,每新加一个数,之前加过的所有数都会多加一遍(点睛之笔!)
class Solution {
public:
int maxSatisfaction(vector<int>& satisfaction) {
sort(satisfaction.rbegin(), satisfaction.rend());
int ans = 0;
int res = 0;
for (int i = 0; i < satisfaction.size(); i++) {
ans += satisfaction[i];
if (ans < 0) break;
res += ans;
}
return res;
}
};
134. 加油站
Note:总油量减去总消耗大于等于零那么一定可以跑完一圈
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int curSum = 0;
int totalSum = 0;
int start = 0;
for (int i = 0; i < gas.size(); i++) {
curSum += gas[i] - cost[i];
totalSum += gas[i] - cost[i];
if (curSum < 0) {
start = i + 1;
curSum = 0;
}
}
if (totalSum < 0) return -1;
return start;
}
};
135. 分发糖果
Note:很有意思的题,掌握贪心思想这题不难
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int> candyVec(ratings.size(), 1);
//从前往后遍历一遍
for (int i = 1; i < ratings.size(); i++) {
if (ratings[i] > ratings[i - 1])
candyVec[i] = candyVec[i - 1] + 1;
}
//从后往前再遍历一遍
for (int i = ratings.size() - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1])
candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
}
int res = 0;
for (int i = 0; i < candyVec.size(); i++)
res += candyVec[i];
return res;
}
};
因为贪心题比较多,就分上下两篇记录了。
贪心没有固定的套路,只要能通过局部最优推导出全局最优就可以尝试贪心了。
贪心更多的是思想与解题技巧。