Leetcode刷题——贪心思想(3/16)

什么是贪心思想

是一种总是选择当前最优的,以期望达到整体最优的方法贪心法一般用于求解最优化问题。采用贪心法求最优化问题的算法,一般都包含一系列步骤,每一步都有一组选择,每次都选择当前最优的选择,希望通过局部最优的选择达到全局最优的选择。贪心法不一定总能产生最优解,可能产生近似解甚至完全不正确的答案,故想使用贪心法,最好是能够能够符合贪心法产生优化解的条件。它的做法大致可以分为以下三步:
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;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值