Javascript算法——贪心算法(一)

贪心算法详解(JavaScript)(局部最优->全局最优)

贪心算法(Greedy Algorithm)是一种在每一步选择中都采取当前状态下的最优选择(局部最优)的算法设计方法。通过局部最优解的累积,试图最终达到全局最优解。尽管贪心算法并不总能保证得到最优解,但它对某些问题(如优化类问题)非常有效。

贪心算法的核心思想
  1. 问题分解:将问题分解成多个子问题。
  2. 贪心选择性质:对每个子问题,做出一个局部最优选择。
  3. 无后效性:当前的选择不会影响后续的决策,或者即使受到影响,也不会导致最优解的丢失。
  4. 重复上述步骤:直到所有子问题解决。
贪心算法的实现步骤
  1. 分析问题是否适合贪心:问题是否满足贪心选择性质和无后效性。
  2. 构造贪心策略:确定如何在每一步选择局部最优解。
  3. 验证贪心策略的正确性:证明或推导出贪心策略能够得到问题的最优解。
  4. 实现代码:利用循环、排序、优先队列等工具编写代码。

经典贪心算法案例及实现

案例 1:分发饼干

问题描述
有两组数据,分别是孩子的胃口数组 g 和饼干大小数组 s。每个孩子只能吃一个饼干,只有当饼干的大小 ≥ 孩子的胃口时,该饼干才能满足该孩子。求最多有多少孩子可以满足。

贪心思路

  1. 将孩子的胃口和饼干大小排序。
  2. 每次将最小的饼干分配给最小胃口的孩子(局部最优)。
  3. 如果当前饼干不能满足孩子,则尝试下一块饼干。

代码实现

function findContentChildren(g, s) {// 排序胃口和饼干大小g.sort((a, b) => a - b);s.sort((a, b) => a - b);let child = 0;let cookie = 0;while (child < g.length && cookie < s.length) {if (s[cookie] >= g[child]) {// 当前饼干可以满足当前孩子child++;}// 尝试分配下一块饼干cookie++;}return child;
}// 示例
console.log(findContentChildren([1, 2, 3], [1, 1])); // 输出: 1
console.log(findContentChildren([1, 2], [1, 2, 3])); // 输出: 2

案例 2:跳跃游戏

问题描述
给定一个非负整数数组,每个元素表示你在该位置最多能跳多远。判断是否可以从数组的第一个位置跳到最后一个位置。

贪心思路

  1. 维护一个变量 maxReach 表示当前能够到达的最远位置。
  2. 遍历数组:
    • 如果当前索引大于 maxReach,则无法跳到当前位置。
    • 否则更新 maxReach 为当前索引加上跳跃步数。
  3. 如果遍历结束时 maxReach 大于等于数组最后一个位置,则说明可以到达。

代码实现

function canJump(nums) {let maxReach = 0;for (let i = 0; i < nums.length; i++) {if (i > maxReach) {// 当前索引无法到达return false;}maxReach = Math.max(maxReach, i + nums[i]);}return true;
}// 示例
console.log(canJump([2, 3, 1, 1, 4])); // 输出: true
console.log(canJump([3, 2, 1, 0, 4])); // 输出: false

案例 3:区间调度问题

问题描述
给定多个区间,求最多能选择不重叠的区间数量。

贪心思路

  1. 按照区间的结束时间升序排序(局部最优:优先选择结束时间最早的区间)。
  2. 遍历区间列表,每次选择当前区间与上一次选择的区间不重叠的区间。

代码实现

function intervalSchedule(intervals) {if (intervals.length === 0) return 0;// 按结束时间升序排序intervals.sort((a, b) => a[1] - b[1]);let count = 1; // 至少有一个区间被选中let end = intervals[0][1];for (let i = 1; i < intervals.length; i++) {if (intervals[i][0] >= end) {// 当前区间与上一个区间不重叠count++;end = intervals[i][1];}}return count;
}// 示例
console.log(intervalSchedule([[1, 3], [2, 4], [3, 5]])); // 输出: 2
console.log(intervalSchedule([[1, 2], [2, 3], [3, 4], [1, 3]])); // 输出: 3

贪心算法的优缺点

优点

  • 简单高效:解决问题的步骤清晰,易于实现。
  • 局部最优:很多时候可以快速找到接近最优的解。

缺点

  • 适用性有限:不适用于所有问题,特别是需要全局视野的问题。
  • 无法回溯:一旦做出选择,就不能回退检查其他可能性。

贪心算法适用场景

  1. 贪心选择性质:整体最优解可以通过一系列局部最优解构成
  2. 无后效性:某一步的决策不会影响后续步骤的最优性。

常见的适用问题包括:最小生成树(Prim、Kruskal 算法)、最短路径问题(Dijkstra 算法)、区间调度、活动选择等。

希望这些内容对你理解和使用贪心算法有所帮助! 😊

贪心算法vs动态规划算法

贪心算法与动态规划算法的比较详解

贪心算法和动态规划是两种常用的算法设计方法,它们各自适用于不同类型的问题,主要区别在于解决问题的思路和适用场景。以下是两者的详细比较:


1. 核心思想
方面贪心算法动态规划
基本思路每一步都选择当前状态下的局部最优解。将问题分解成多个子问题,利用子问题的解构造全局最优解。
全局性通过局部最优推导全局最优解。通过递推式逐步解决子问题以达到全局最优解。

2. 适用问题
方面贪心算法动态规划
问题类型适用于具有贪心选择性质和无后效性的优化问题。适用于有重叠子问题和最优子结构性质的问题。
典型问题活动选择、最小生成树、最短路径(Dijkstra)。背包问题、最长公共子序列、最长递增子序列。

3. 实现复杂度
方面贪心算法动态规划
实现难度相对简单,直接选择当前最优解即可。需要设计状态、递推关系和表格存储。
时间复杂度通常为 ( O(n \log n) ) 或 ( O(n) )。通常为 ( O(n^2) ) 或更高。
空间复杂度一般为 ( O(1) )。需要额外的存储空间(例如表格),通常为 ( O(n^2) )。

4. 解决过程
方面贪心算法动态规划
过程描述通过排序、优先队列等工具选择局部最优。使用状态转移方程递推计算,通常自底向上。
回溯性无法回溯,一旦选择即固定。可以通过存储子问题结果进行回溯。

5. 优势与局限性
方面贪心算法动态规划
优势高效、简单,适用于实时计算。可以保证得到全局最优解。
局限性不保证全局最优解,适用问题较少。复杂度较高,消耗更多的时间和空间资源。

贪心算法与动态规划的对比表格总结

属性贪心算法动态规划
选择方式每一步选择局部最优解依赖子问题结果,通过递推求解全局最优解
适用问题特性贪心选择性质、无后效性重叠子问题、最优子结构
时间复杂度通常较低通常较高
空间复杂度通常为 ( O(1) )需要额外存储,通常为 ( O(n^2) )
实现难度简单,逻辑清晰需要设计状态转移方程,难度较高
回溯性不可回溯可通过记录表格结果回溯
保证最优解不一定(除非证明问题适合贪心)一定能保证最优解
典型应用活动选择、最小生成树、最短路径背包问题、最长公共子序列、斐波那契数列

两种算法的使用场景总结

  1. 贪心算法

    • 问题适合贪心选择,且有无后效性。
    • 需要快速计算的近似解或简单解。
    • 例子:找零问题、最小生成树、区间调度。
  2. 动态规划

    • 问题有重叠子问题和最优子结构。
    • 不确定贪心是否适用,但需要保证最优解。
    • 例子:背包问题、最长公共子序列、股票买卖问题。

总结:贪心算法和动态规划在解决问题时各有侧重。对于简单、高效的场景可以优先考虑贪心算法,而对于复杂、全局优化的问题则更适合动态规划。

摆动序列

在这里插入图片描述
在这里插入图片描述

核心:考虑这三种情况!!!

在这里插入图片描述
在这里插入图片描述

/*** @param {number[]} nums* @return {number}*/
var wiggleMaxLength = function(nums) {// let len=nums.length;// let strLen=0;// let preDiff=0,curDiff=0,count=0;// //判断字符序列是否为长度,是偶数的话// //还需比较最后两个数组的大小是否大于0// let flag=nums.length%2;// for(let i=0,j=1;j<nums.length;i++,j++){//     curDiff=nums[j]-nums[i];//     if(preDiff>0&&curDiff<0){//         count++;//     }//     if(j===nums.length-1&&!flag&&curDiff>0){//         strLen=count>=1?2*count+2:2;//     }else{//         strLen=count>=1?2*count+1:2;//     }//     preDiff=curDiff;// }// return  strLen;//考虑平坡、单调平坡和收尾元素//默认尾部元素有个坡//preDiff=0可起到前方有个和开始元素值一样的虚拟元素if(nums.length<=1)return nums.length;let preDiff=0,curDiff=0,res=1;//i<nums.length-1  默认尾部元素有个坡for(let i=0;i<nums.length-1;i++){curDiff=nums[i+1]-nums[i];if((curDiff>0&&preDiff<=0)||(curDiff<0&&preDiff>=0)){res++;//在这赋值curDiff,表示只有坡度方向变化时才更新preDiff//防止在单调平坡上出现errorpreDiff=curDiff;}}return res;
};

最大子序列和

在这里插入图片描述
在这里插入图片描述

核心:怎样用代码重新开始位置,其实此题返回值,直接将前面累加和赋值0就行! if(curSum<0)curSum=0;

/*** @param {number[]} nums* @return {number}*/
var maxSubArray = function(nums) {// let res=-Infinity;let res=[];for(let i=0;i<nums.length;i++){curSum+=nums[i];if(curSum>res)res=curSum;//!!!核心,更换起始位置就是把当前curSum赋值为0就行!if(curSum<0)curSum=0;}return res; // for(let i=0;i<nums.length;i++){//     let curSum=0;//     for(let j=i;j<nums.length;j++){//         curSum+=nums[j];//         res.push(curSum);//     }// }// let maxArr=res.sort((a,b)=>b-a)[0];// return maxArr;};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/66507.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CK18——肝损伤无创诊断标志物

肝脏作为人体至关重要的代谢与解毒器官&#xff0c;极易遭受病毒、药物、酒精及不良饮食等多种因素的损害&#xff0c;进而引发一系列如非酒精性脂肪肝&#xff08;NAFLD&#xff09;、肝纤维化、肝硬化、肝细胞癌以及各类肝炎等病症。因此&#xff0c;确定一种高可靠性、非侵入…

.NET Core + Kafka 开发指南

什么是Kafka Apache Kafka是一个分布式流处理平台,由LinkedIn开发并开源,后来成为Apache软件基金会的顶级项目。Kafka主要用于构建实时数据管道和流式应用程序。 Kafka 架构 从下面3张架构图中可以看出Kafka Server 实际扮演的是Broker的角色, 一个Kafka Cluster由多个Bro…

[离线数仓] 总结二、Hive数仓分层开发

接 [离线数仓] 总结一、数据采集 5.8 数仓开发之ODS层 ODS层的设计要点如下: (1)ODS层的表结构设计依托于从业务系统同步过来的数据结构。 (2)ODS层要保存全部历史数据,故其压缩格式应选择压缩比率,较高的,此处选择gzip。 CompressedStorage - Apache Hive - Apac…

Unity3D仿星露谷物语开发19之库存栏丢弃及交互道具

1、目标 从库存栏中把道具拖到游戏场景中&#xff0c;库存栏中道具数相应做减法或者删除道具。同时在库存栏中可以交换两个道具的位置。 2、UIInventorySlot设置Raycast属性 在UIInventorySlot中&#xff0c;我们只希望最外层的UIInventorySlot响应Raycast&#xff0c;他下面…

阿里云代理商热销产品推荐

在数字化浪潮的推动下&#xff0c;企业对于云计算的依赖日益加深。阿里云&#xff0c;作为中国领先的云计算服务提供商&#xff0c;为企业提供了丰富多样的云产品和服务。本文将聚焦于阿里云代理商热销产品推荐&#xff0c;探讨其如何帮助企业高效利用云资源&#xff0c;加速数…

江科大STM32入门——IIC通信笔记总结

wx&#xff1a;嵌入式工程师成长日记 &#xff08;一&#xff09;简介 STM32内部集成了硬件I2C收发电路&#xff0c;可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能&#xff0c;减轻CPU的负担 支持多主机 支持7位/10位地址模式 支持不同的通讯速…

MySQL安装,配置教程

一、Linux在线yum仓库安装 打开MySQL官方首页&#xff0c;链接为&#xff1a;https://www.mysql.com/ 界面如下&#xff1a; 在该页面中找到【DOWNOADS】选项卡&#xff0c;点击进入下载页面。 在下载界面中&#xff0c;可以看到不同版本的下载链接&#xff0c;这里选择【My…

四、VSCODE 使用GIT插件

VSCODE 使用GIT插件 一下载git插件与git Graph插件二、git插件使用三、文件提交到远程仓库四、git Graph插件 一下载git插件与git Graph插件 二、git插件使用 git插件一般VSCode自带了git&#xff0c;就是左边栏目的图标 在下载git软件后vscode的git插件会自动识别当前项目 …

消息队列MQ(二)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 MQ学习笔记 前言一、发送者的可靠性1. 生产者重试机制2. 生产者确认机制3. 实现生产者确认 二、MQ的可靠性1. 数据持久化2. LazyQueue 前言 在用MQ实现异步调用时&#xff0…

数据分析思维(九):分析方法——AARRR模型分析方法

数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…

【计算机网络】课程 实验四 配置快速生成树协议(RSTP)

实验四 配置快速生成树协议&#xff08;RSTP&#xff09; 一、实验目的 1&#xff0e;理解快速生成树协议RSTP的工作原理。 2&#xff0e;掌握如何在交换机上配置快速生成树。 二、实验分析与设计 【背景描述】 某学校为了开展计算机教学和网络办公&#xff0c;建立了一个计…

Tauri教程-基础篇-第一节 Tauri项目创建及结构说明

“如果结果不如你所愿&#xff0c;就在尘埃落定前奋力一搏。”——《夏目友人帐》 “有些事不是看到了希望才去坚持&#xff0c;而是因为坚持才会看到希望。”——《十宗罪》 “维持现状意味着空耗你的努力和生命。”——纪伯伦 Tauri 技术教程 * 第四章 Tauri的基础教程 第一节…

pyinstaller冻结打包多进程程序的bug:无限创建进程直至系统崩溃

前面写过两篇相关的文章&#xff1a; PyQt应用程序打包Python自动按键 这两篇文章都没有提到下面的这个重要问题&#xff1a; 采用Pyinstaller冻结打包多进程程序时&#xff0c;必须非常小心。这个技术线在Windows上会有一个非常严重的Bug。直接运行打包后的程序会造成无限创…

网络安全-kail linux 网络配置(基础篇)

一、网络配置 1.查看网络IP地址&#xff0c; 我的kail&#xff1a;192.168.15.128 使用ifconfig查看kail网络连接情况&#xff0c;ip地址情况 又复制了一台kail计算机的IP地址。 再看一下windows本机&#xff1a;使用ipconfig进行查看&#xff1a; 再看一下虚拟机上的win7I…

uni app 写的 小游戏,文字拼图?文字拼写?不知道叫啥

从下方的偏旁部首中选在1--3个组成上面文章中的文字&#xff0c;完成的文字标红 不喜勿喷 《满江红》 其中用到了两个文件 strdata.json parameters.json 这两个文件太大 放到资源中了 资源文件 <template><view class"wenzi_page_main"><view c…

分享几个高清无水印国外视频素材网站

在数字内容创作日益盛行的今天&#xff0c;高质量的视频素材成为了视频制作、广告创意和多媒体项目中不可或缺的元素。对于追求专业水准的创作者而言&#xff0c;高清、无水印的视频素材是确保作品质量的基石。以下将分享几个优质的视频素材网站&#xff0c;为您的创作之路提供…

【LLM】大语言模型基础知识及主要类别架构

文章目录 LLM大语言模型1.LLM基础知识1.1大模型介绍:1.2语言模型1.21n-gram语言模型1.22神经网络语言模型1.23基于Transformer的预训练语言模型1.24大语言模型 1.3模型评估指标1.31 BLEU1.32 Rouge指标1.33 困惑度PPL 2.LLM主要类别架构2.1 自编码模型2.2 自回归模型2.3 Encode…

剖析 Claim-Check 模式:以小传大,赋能分布式系统与微服务

1. 前言 1.1 写作背景与目的 在当今分布式系统与微服务架构盛行的时代&#xff0c;服务间的消息传递与数据交换越来越频繁。传统的消息传输在面对海量数据时&#xff0c;往往会遇到以下痛点&#xff1a; 消息体过大&#xff1a;直接通过消息队列或服务间接口发送大体量数据&…

【Uniapp-Vue3】v-if条件渲染及v-show的选择对比

如果我们想让元素根据响应式变量的值进行显示或隐藏可以使用v-if或v-show 一、v-show 另一种控制显示的方法就是使用v-show&#xff0c;使用方法和v-if一样&#xff0c;为true显示&#xff0c;为false则不显示。 二、v-if v-if除了可以像v-show一样单独使用外&#xff0c;还…

JVM实战—OOM的定位和解决

1.如何对系统的OOM异常进行监控和报警 (1)最佳的解决方案 最佳的OOM监控方案就是&#xff1a;建立一套监控平台&#xff0c;比如搭建Zabbix、Open-Falcon之类的监控平台。如果有监控平台&#xff0c;就可以接入系统异常的监控和报警&#xff0c;可以设置当系统出现OOM异常&…