贪心加动态,最值跑不掉

贪心

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. 贪心算法:

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

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

相关推荐
完球了18 分钟前
【Day02-JS+Vue+Ajax】
javascript·vue.js·笔记·学习·ajax
前端没钱19 分钟前
若依Nodejs后台、实现90%以上接口,附体验地址、源码、拓展特色功能
前端·javascript·vue.js·node.js
学地理的小胖砸23 分钟前
【高分系列卫星简介】
开发语言·数码相机·算法·遥感·地理信息
爱喝水的小鼠24 分钟前
AJAX(一)HTTP协议(请求响应报文),AJAX发送请求,请求问题处理
前端·http·ajax
dgiij25 分钟前
AutoX.js向后端传输二进制数据
android·javascript·websocket·node.js·自动化
叫我:松哥40 分钟前
基于机器学习的癌症数据分析与预测系统实现,有三种算法,bootstrap前端+flask
前端·python·随机森林·机器学习·数据分析·flask·bootstrap
让开,我要吃人了43 分钟前
HarmonyOS鸿蒙开发实战(5.0)网格元素拖动交换案例实践
前端·华为·程序员·移动开发·harmonyos·鸿蒙·鸿蒙开发
谢尔登1 小时前
Webpack 和 Vite 的区别
前端·webpack·node.js
谢尔登1 小时前
【Webpack】Tree Shaking
前端·webpack·node.js
yanyanwenmeng1 小时前
matlab基础
开发语言·算法·matlab