贪心加动态,最值跑不掉

贪心

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

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

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

相关推荐
遇到困难睡大觉哈哈11 分钟前
JavaScript面向对象
开发语言·javascript·ecmascript
檀越剑指大厂14 分钟前
【Python系列】异步 Web 服务器
服务器·前端·python
我是Superman丶16 分钟前
【前端】js vue 屏蔽BackSpace键删除键导致页面后退的方法
开发语言·前端·javascript
Hello Dam18 分钟前
基于 Spring Boot 实现图片的服务器本地存储及前端回显
服务器·前端·spring boot
小仓桑19 分钟前
利用 Vue 组合式 API 与 requestAnimationFrame 优化大量元素渲染
前端·javascript·vue.js
Hacker_xingchen19 分钟前
Web 学习笔记 - 网络安全
前端·笔记·学习
天海奈奈20 分钟前
前端应用界面的展示与优化(记录)
前端
qq_4856689931 分钟前
算法习题--蓝桥杯
算法·职场和发展·蓝桥杯
waves浪游34 分钟前
类和对象(中)
c语言·开发语言·数据结构·c++·算法·链表
做人不要太理性38 分钟前
【算法一周目】滑动窗口(2)
c++·算法·leetcode·哈希算法·散列表·滑动窗口