Skip to content

Latest commit

 

History

History
87 lines (62 loc) · 4.03 KB

贪心算法.md

File metadata and controls

87 lines (62 loc) · 4.03 KB

贪心算法

贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择,也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。贪心算法是一种算法思想,不是某个具体的算法。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。贪心算法一般会将求解过程分为若干个步骤,每个步骤都应用弹性原则,选取当前状态下最优的选择,并希望最后的结果也是最优的解。

算法思路

贪心算法一般按照如下步骤进行:

  • 建立数学模型描述问题。
  • 把求解的问题分成若干个子问题。
  • 对每个子问题,得到子问题的局部最优解。
  • 把子问题的局部最优解合成整体问题的一个解。

贪心算法是一种对某些求最优解问题的更简单,更迅速的设计技术。贪心算法的特点是一步一步地进行,常以当前情况为基础做出局部最优选择,二不考虑各种可能的整体情况,省去了穷尽所有可能所耗费的大量时间。贪心算法采用自顶向下,以迭代的形式做出相继的贪心选择,每一次贪心选择,就是将所求问题简化为一个规模更小的子问题,通过一步一步的贪心选择,可得到整体问题的最优解。

使用条件

利用贪心算法求解问题应具备以下两个特征:

  1. 贪心选择性质

一个问题的整体最优解可以通过一系列局部最优解达到,即在做选择时,总是以当前的情况为基础做出最优选择,而不用考虑其他子问题的解,并且每次的选择可以依赖以前作出的选择,但不依赖后面要作出的选择,贪心策略必须具备无后效性,即贪心选择不能回退。对一一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作出的贪心选择最终会得到问题的整体最优解。

  1. 最优子结构性质

当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键所在。

存在的问题

贪心算法存在以下的问题:

  1. 不能保证整体解是最优的。因为贪心算法总是从局部出发,并没有从整体上考虑。
  2. 贪心算法一般用来求解最大或最小的解。
  3. 贪心算法只能确定某些问题的可行性范围。

示例

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

示例 1:

输入: g = [1,2,3], s = [1,1]
输出: 1
解释: 
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。

示例 2:

输入: g = [1,2], s = [1,2,3]
输出: 2
解释: 
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.

贪心策略:为了尽可能满足最多数量的孩子,每次都选择可以满足孩子胃口值的最小尺寸的饼干。

解题思路:升序+双指针+贪心

var findContentChildren = function(g, s) {
    // 升序
    g.sort((a, b) => a -b);
    s.sort((a, b) => a - b);
    const sLen = s.length;
    // 双指针 g和s匹配上两个指针同时移动
    // 匹配不上 g的指针自己移动
    let j = 0;
    let result = 0;
    for (let i = 0; i < sLen; i++) {
        if (s[i] >= g[j]) {
            result++;
            j++;
        }
    }
    return result;
};