什么是贪心思想
是一种总是选择当前最优的,以期望达到整体最优的方法贪心法一般用于求解最优化问题。采用贪心法求最优化问题的算法,一般都包含一系列步骤,每一步都有一组选择,每次都选择当前最优的选择,希望通过局部最优的选择达到全局最优的选择。贪心法不一定总能产生最优解,可能产生近似解甚至完全不正确的答案,故想使用贪心法,最好是能够能够符合贪心法产生优化解的条件。它的做法大致可以分为以下三步:
a、确定贪心策略
b、根据贪心策略,一步一步得到局部最优解
c、将局部最优解合并起来就得到全局最优解
开始刷题
- 455. Assign Cookies (Easy)
- 435. Non-overlapping Intervals (Medium)
- 452. Minimum Number of Arrows to Burst Balloons (Medium)
- 406. Queue Reconstruction by Height(Medium)
- 121. Best Time to Buy and Sell Stock (Easy)
- 122. Best Time to Buy and Sell Stock II (Easy)
- 605. Can Place Flowers (Easy)
- 392. Is Subsequence (Medium)
- 665. Non-decreasing Array (Easy)
- 53. Maximum Subarray (Easy)
- 763. Partition Labels (Medium)
455 分发饼干
var findContentChildren = function (g, s) {
g.sort((a, b) => a - b);
s.sort((a, b) => a - b);
let gi = 0, si = 0;
while (gi < g.length && si < s.length) {
if (g[gi] <= s[si]) {
gi++;
}
si++;
}
return gi;
};
435 无重叠区域
var eraseOverlapIntervals = function (intervals) {
if (!intervals.length) return null;
intervals.sort((a, b) => a[1] - b[1]);
let end = intervals[0][1];
let count = 0;
for (let i = 1; i < intervals.length; i++) {
if (intervals[i][0] < end) {
count++;
continue; //不要落下
}
end = intervals[i][1];
}
return count;
};
452. 用最少数量的箭引爆气球
提示:与上题区别仅为 [1, 2] 和 [2, 3] 在本题中算是重叠区间。
var findMinArrowShots = function (points) {
points.sort((a, b) => a[1] - b[1]);
let count = 1;
let end = points[0][1];
for (let i = 1; i < points.length; i++) {
if (points[i][0] <= end) {
continue;
}
count++;
end = points[i][1];
}
return count;
};
406. 根据身高重建队列
var reconstructQueue = function (people) {
people.sort((a, b) => b[0] === a[0] ? a[1] - b[1] : b[0] - a[0]);
let ans = [];
people.forEach((one) => {
ans.splice(one[1],0,one);
})
return ans;
};
121. 买卖股票的最佳时机
tips:只要记录前面的最小价格,将这个最小价格作为买入价格,然后将当前的价格作为售出价格,查看当前收益是不是最大收益。
var maxProfit = function (prices) {
const { length } = prices;
let max = 0;
let minItem = prices[0];
for (let i = 1; i < length; i++) {
if (prices[i] < minItem) {
minItem = prices[i];
continue;
}
max = prices[i] - minItem > max ? prices[i] - minItem : max;
}
return max;
};
122. 买卖股票的最佳时机 II
tips: 对于 [a, b, c, d],如果有 a <= b <= c <= d ,那么最大收益为 d - a。而 d - a = (d - c) + (c - b) + (b - a) ,因此当访问到一个 prices[i] 且 prices[i] - prices[i-1] > 0,那么就把 prices[i] - prices[i-1] 添加到收益中。
var maxProfit = function (prices) {
const { length } = prices;
let res = 0;
for (let i = 1; i < length; i++) {
if (prices[i] - prices[i - 1] > 0) {
res += prices[i] - prices[i - 1];
}
}
return res;
}
605. 种花问题
不一定开头和结尾都是1
var canPlaceFlowers = function (flowerbed, n) {
const { length } = flowerbed;
let count = 0;
for (let i = 0; i < length && count < n; i++) {
if (flowerbed[i] === 1) {
continue;
}
let pre = i == 0 ? 0 : flowerbed[i - 1];
let next = i == length - 1 ? 0 : flowerbed[i + 1];
if (pre === 0 && next === 0) {
count++;
flowerbed[i] = 1;
}
}
return count >= n;
};
392. 判断子序列
indexOf
var isSubsequence = function (s, t) {
let strT = t;
let index = -1;
for (let i = 0; i < s.length; i++) {
index = strT.indexOf(s[i], index + 1);
if (index === -1) {
return false;
}
}
return true;
};
665. 非递减数列
在这里插入代码片
53. 最大子序和
var maxSubArray = function (nums) {
const { length } = nums;
let preSum = nums[0];
let maxSum = nums[0];
for (let i = 1; i < length; i++) {
preSum = preSum > 0 ? preSum + nums[i] : nums[i];
maxSum = Math.max(maxSum, preSum);
}
return maxSum;
};
763. 划分字母区间
var partitionLabels = function (S) {
let maxPos = {};
for (let i = 0; i < S.length; i++) {
maxPos[S[i]] = i; //存储每个字符的最远索引
}
let res = [];
let end = 0;
let start = 0;
for (let i = 0; i < S.length; i++) {
end = Math.max(maxPos[S[i]], end); //片段中的最远索引
if (i === end) { //这个片段结束
res.push(i - start + 1);
start = i + 1; //下一片段的起始位置
}
}
return res;
};