sisterAn/JavaScript-Algorithms

字节&leetcode455:分发饼干

sisterAn opened this issue · 4 comments

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 s。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

注意:

你可以假设胃口值为正。
一个小朋友最多只能拥有一块饼干。

示例 1:

输入: [1,2,3], [1,1]

输出: 1

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

示例 2:

输入: [1,2], [1,2,3]

输出: 2

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

leetcode

let gArr = [1,2] // 小孩的胃值
let sArr = [1,2,3] // 饼干的能量值
let maxNum = 0 // 可以分配的最大数

// 获取最大值以及下标
const getMaxAndIndexs = function (arr) {
  const max = arr.length > 0 ? Math.max(...arr) : -1
  const indexs = []
  for (let index = 0; index < arr.length; index++) {
    const element = arr[index];
    if (element === max) {
      indexs.push(index)
    }
  }
  indexs.reverse()
  return {
    max,
    indexs
  }
}

// 指定下标出栈
const spliceElement = function(indexs, arr) {
  indexs.forEach(item => {
    arr.splice(item, 1)
  })
}

// 算法主函数
const distributionBiscuits = function () {
  if (sArr.length > 0 && gArr.length > 0) {
    let sMax = getMaxAndIndexs(sArr).max
    let sIndexs = getMaxAndIndexs(sArr).indexs
    let gMax = getMaxAndIndexs(gArr).max
    let gIndexs = getMaxAndIndexs(gArr).indexs
    if (sMax < gMax) {
      // 如果饼干能量没有符合最高胃值的 则胃值出栈继续下一个
      spliceElement(gIndexs, gArr)
      distributionBiscuits()
    } else {
      if (sIndexs.length <= gIndexs.length) {
        // 如果饼干能量的数量小于等于胃值 两个全部出栈
        maxNum += sIndexs.length
        spliceElement(sIndexs, sArr)
        spliceElement(gIndexs, gArr)
        distributionBiscuits()
      } else {
        // 如果饼干能量的数量大于等于胃值 胃值全部出栈 饼干能量按胃值数量出栈
        maxNum += gIndexs.length
        const flagIndex = sIndexs.slice(0, gIndexs.length)
        spliceElement(flagIndex, sArr)
        spliceElement(gIndexs, gArr)
        distributionBiscuits()
      }
    }
  }
  return maxNum
}
console.log(distributionBiscuits())
var findContentChildren = function(g, s) {
    g.sort((a, b) => {return a - b});
    s.sort((a, b) => {return a - b});
    console.log(g, s)
    let gi = 0, si = 0;
    while (gi < g.length && si < s.length) {
        if (g[gi] <= s[si]) {
            gi++;
        }
        si++;
    }
    return gi;
};

解法:贪心算法

const findContentChildren = (g, s) => {
    if (!g.length || !s.length) return 0
    
    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++
    }
    return gi
}

leetcode

/**
 * @param {number[]} g
 * @param {number[]} s
 * @return {number}
 */
var findContentChildren = function(g, s) {
    let count = 0
    // 排序
    g.sort((v1,v2) => {
        return v1-v2
    })
    s.sort((v1,v2) => {
        return v1-v2
    })
    let len = g.length, j = 0
    for (let i = 0; i < s.length; i++) {
        if (j >= len) break
        if (s[i] < g[j]) continue
        j++
        count++
    }
    return count
};