贪心加动态,最值跑不掉

贪心

leetcode 455 分饼干

该问题需要尽可能多地满足孩子的需求,并且每个孩子只能分配一块饼干。输入参数 g 和 s 分别代表孩子的需求和饼干的大小,任务是计算最多能够满足多少孩子的需求。

js 复制代码
//暴力破解 逻辑 O(n^2)
//O(nlogN) 快排  归并排序  排序+双指针
//策略 双指针
var findContentChildren = function(g, s) {
    g = g.sort((a,b)=>a-b)
    s = s.sort((a,b)=>a-b)

    let gi = 0
    let sj = 0
    let res = 0
    while(gi<g.length&&sj<s.length){
        if(s[sj]>=g[gi]){  //当下
            gi++;
            sj++;
            res++;
        }else{
            sj++;
        }
    }
    return res
}
console.log(findContentChildren([1,2], [1,2,3]));

这段代码使用了贪心算法解决该问题,其核心思想是每次都选择当前情况下的最优解,而不考虑未来的影响。具体实现步骤如下:

  1. 对孩子的需求和饼干的大小进行升序排序,方便后续比较大小。
  2. 定义两个指针 gi 和 sj,分别指向孩子的需求和饼干的大小数组的起始位置。
  3. 依次比较孩子的需求和饼干的大小,如果饼干的大小大于等于孩子的需求,则将该饼干分配给该孩子,同时将 gi 和 sj 指针都向后移动一位,并累加满足的孩子数量。
  4. 如果饼干的大小小于孩子的需求,则只将 sj 指针向后移动一位。
  5. 重复步骤 3 和 4,直到 gi 或 sj 超出数组的范围。
  6. 返回满足需求的孩子数量。

在该代码实现中,时间复杂度为 O(nlogn),其中 n 为孩子的需求和饼干的大小数组的长度。

动态规划

leetcode 198 打家劫舍

该问题描述了一排房屋,每个房屋内有一定数量的现金。相邻的房屋在同一晚上被闯入会触发警报系统,因此不能连续盗窃相邻的房屋。任务是计算在不触发警报的情况下,能够获得的最大金额。

js 复制代码
var rob = function (nums) {
    //没有状态转移方程不要动手
    const dp=[] //最优子结构,O(n) 一维数组,缓存状态结果
    dp[0] = 0
    dp[1] = 0
    for(let i=2;i<nums.length+2;i++){
        dp[i] = Math.max(dp[i-2]+nums[i-2],dp[i-1])
    }
    return dp[dp.length-1]
}

console.log(robTo([1,2,3,1])); //最优

这段代码使用了动态规划的思想来解决该问题。动态规划通过定义状态转移方程,利用之前的计算结果来推导出当前的最优解。具体实现步骤如下:

  1. 定义一个一维数组 dp,用于缓存状态结果,其中 dp[i] 表示打劫前 i 个房屋能够获得的最大金额。
  2. 初始化 dp[0]dp[1] 为 0,表示前 0 个和前 1 个房屋都无法打劫。
  3. 使用循环从第 2 个房屋开始遍历到最后一个房屋(即 i 从 2 取值到 nums.length + 1),并根据状态转移方程计算 dp[i] 的值。
  4. 状态转移方程为 dp[i] = Math.max(dp[i-2] + nums[i-2], dp[i-1]),表示在打劫第 i 个房屋时有两种选择:打劫或不打劫。如果打劫第 i 个房屋,则能获得的最大金额为 dp[i-2] + nums[i-2];如果不打劫第 i 个房屋,则能获得的最大金额为 dp[i-1]。取两者中较大的值作为 dp[i] 的结果。
  5. 循环结束后,返回 dp[dp.length-1],即最后一个房屋处能够获得的最大金额。

在该代码实现中,时间复杂度为 O(n),其中 n 为房屋数量。因为只需遍历一次房屋数组,计算出每个位置的状态结果即可。

最值问题

在动态规划和贪心算法中,最值问题的解决方法取决于问题的特性。下面对这两种方法进行简要的分析:

  1. 动态规划:

    • 适用情况:动态规划适用于具有最优子结构和重叠子问题特性的问题。当原问题的最优解可以通过子问题的最优解推导出,并且多个问题需要解决同一个子问题时,通常可以使用动态规划。
    • 解决方式:动态规划通过将原问题分解成若干子问题,计算并存储子问题的解,然后利用之前计算得到的结果来推导当前问题的解。这种自底向上的推导过程可以避免重复计算,提高效率。
  2. 贪心算法:

    • 适用情况:贪心算法适用于局部最优解独立且不需要推导出原问题的情况。在贪心算法中,每一步都选择当前状态下的最优解,而不考虑之前的状态或之后的影响。如果子问题之间不存在重叠,并且当前的最优选择不会影响后续步骤的选择,通常可以考虑使用贪心算法。
    • 解决方式:贪心算法每一步都选择局部最优解,并且相信这些局部最优解能够推导出全局最优解。因为贪心算法不需要回溯或者推导子问题的解,所以在某些情况下可能会更加直观和简单。

综上所述,动态规划适用于具有最优子结构和重叠子问题特性的问题,而贪心算法适用于局部最优解独立且不需要推导出原问题的情况。在解决最值问题时,根据问题的特性选择合适的方法可以帮助我们更高效地解决问题。

相关推荐
try again!2 分钟前
rollup.js 和 webpack
开发语言·javascript·webpack
阿镇吃橙子3 分钟前
一些手写及业务场景处理问题汇总
前端·算法·面试
庸俗今天不摸鱼4 分钟前
【万字总结】前端全方位性能优化指南(九)——FSP(First Screen Paint)像素级分析、RUM+合成监控、Lighthouse CI
前端·性能优化
逆袭的小黄鸭4 分钟前
JavaScript:作用域与作用域链的底层逻辑
前端·javascript·面试
用户26124583401615 分钟前
vue2实现滚动条自动滚动
前端
酱酱哥玩AI7 分钟前
Trae编译器:实现多目标班翠鸟优化算法(IPKO)无人机路径规划仿真(Python版),完整代码
算法
FanetheDivine9 分钟前
实现"选中表格项将元素加入集合"的动画效果
javascript·vue.js
前端Hardy9 分钟前
HTML&CSS:超好看的轮播图,你绝对用得上(建议收藏)
javascript·css·html
傻球13 分钟前
Jotai 使用详解:React 轻量级状态管理库
前端·react.js