IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 贪心算法专题 -> 正文阅读

[数据结构与算法]贪心算法专题

目录

🌞贪心算法概念

🌻算法思想

🌻基本思路

🌂贪心例题

?选择排序

?平衡字符串

?买卖股票的最佳时机Ⅱ

?跳跃游戏

?最多可以参加的会议数目

?无重叠区间

😀总结

🌈贪心策略

🌈该算法存在的问题


🌞贪心算法概念

🌻算法思想

贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素。

当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。运用贪心策略在每一次转化时都取得了最优解。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。贪心算法的每一次操作都对结果产生直接影响。

🌻基本思路

从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止。

🌂贪心例题

?选择排序

选择排序是最经典的贪心算法问题,我们可以从选择排序入手,来了解贪心算法的代码。

public static void selectSort(int[] array) {
    for (int i = 0; i < array.length; i++) {
        //记录 最小值的下标
        int minIndex = i;
        //贪心:每次从未排序数组中找到最小值
        for ( int j = i+1; j < array.length; j++) {
            if(array[j] < array[minIndex]) {
                minIndex = j;
            }
        }
        //把最小值放在没排序的最前端
        swap(array,minIndex,i);
    }
}
private static void swap(int[] array,int i,int j) {
    int tmp = array[i];
    array[i] = array[j];
    array[j] = tmp;
}

?平衡字符串

题目

????????在一个?平衡字符串?中,'L'?和?'R'?字符的数量是相同的。

????????给你一个平衡字符串?s,请你将它分割成尽可能多的平衡字符串。

示例

????????输入:s = "RLRRLLRLRL"

????????输出:4

????????解释:s 可以分割为 "RL"、"RRLL"、"RL"、"RL" ,每个子字符串中都包含相同数量的 'L' 和 'R' 。

贪心策略

????????如果出现平衡状态,如"RRLL"、"RL",立刻分割并计数。

class?Solution?{
????public?int?balancedStringSplit(String?s)?{
????????int?count=0;
????????int?balance=0;
????????for(int?i=0;i<s.length();++i){
            //如果出现R就++出现L就--
????????????if(s.charAt(i)=='R'){
????????????????balance++;
????????????}else{
????????????????balance--;
????????????}
            //平衡就意味着L和R个数相等,即banlance为0了
????????????if(balance==0){
                //计数
????????????????count++;
????????????}
????????}
????????return?count;
????}
}

?买卖股票的最佳时机Ⅱ

💧这道题的题目是不是有点熟悉,买卖股票的最佳时机Ⅰ是动态规划算法专题里的例题。

题目

????????给你一个整数数组 prices ,其中?prices[i] 表示某支股票第 i 天的价格。

????????在每一天,你可以决定是否购买和/或出售股票。你在任何时候?最多?只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

????????返回 你能获得的 最大 利润?。

示例

????????输入:prices = [7,1,5,3,6,4]

????????输出:7

????????解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。总利润为 4 + 3 = 7 。

贪心策略

????????只要相比前一天,股票涨了,那就在进行买卖。

class?Solution?{
????public?int?maxProfit(int[]?prices)?{
????????int?count=0;
????????for(int?i=1;i<prices.length;++i){
            //只要股票能涨价,咱就买卖
????????????if(prices[i-1]<prices[i]){
????????????????count+=prices[i]-prices[i-1];
????????????}
????????}
????????return?count;
????}
}

?跳跃游戏

题目

????????给定一个非负整数数组?nums ,你最初位于数组的 第一个下标 。

????????数组中的每个元素代表你在该位置可以跳跃的最大长度。

????????判断你是否能够到达最后一个下标。

示例

????????输入:nums = [2,3,1,1,4]

????????输出:true

????????解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

贪心策略

????????向后遍历数组,每一步都更新可以到达的最远位置,如果最远位置包含了最后的元素,那么就返回true

class?Solution?{
????public?boolean?canJump(int[]?nums)?{
????????int?max=0;
????????for(int?i=0;i<nums.length;++i){
            //如果跳的到第i点
????????????if(max>=i){
                //那就更新最远跳跃距离
????????????????max=Math.max(max,i+nums[i]);
                //最远跳跃距离包含最后一点,就可以直接返回true了
????????????????if(max>=nums.length-1){
????????????????????return?true;
????????????????}
            //跳不到第i点那就永远也跳不过去
????????????}else{
????????????????return?false;
????????????}
????????}
????????return?true;
????}
}

?最多可以参加的会议数目

题目

????????给你一个数组?events,其中?events[i] = [startDayi, endDayi]?,表示会议?i?开始于?startDayi?,结束于?endDayi?。

????????你可以在满足?startDayi?

????????请你返回你可以参加的?最大?会议数目。

示例

????????输入:events = [[1,2],[2,3],[3,4]]

????????输出:3

????????解释:你可以参加所有的三个会议。安排会议的一种方案如上图。

????????????????????????第 1 天参加第一个会议。

????????????????????????第 2 天参加第二个会议。

????????????????????????第 3 天参加第三个会议。

示例

????????输入:events= [[1,2],[2,3],[3,4],[1,2]]

????????输出:4

贪心策略

????????优先选择会议结束时间早的

class?Solution?{
????public?int?maxEvents(int[][]?events)?{
????????//按开始时间排序
????????Arrays.sort(events,?(a,?b)->(a[0]-b[0]));
????????//优先队列(小根堆),存会议结束的时间
????????PriorityQueue<Integer>?queue?=?new?PriorityQueue<>();

????????int?result?=?0;
????????int?start?=?events[0][0];
????????int?index?=?0;
????????
????????//还有会议没开始或还有会议没结束,就进入循环
????????while(index?<?events.length?||?!queue.isEmpty()){
????????????//把开始时间相同的,放入堆中,比较结束时间,谁先结束就选谁
????????????while(index?<?events.length?&&?events[index][0]?==?start){
????????????????queue.offer(events[index][1]);
????????????????index++;
????????????}
????????????//把开始时间之前已经结束的删除
????????????while(!queue.isEmpty()?&&?queue.peek()?<?start){
????????????????queue.poll();
????????????}

????????????//如果队列不空,还有会议没结束,那么队头,就是结束时间最早的会议,参加他
????????????if(!queue.isEmpty()){
????????????????queue.poll();
????????????????result++;
????????????}
????????????//下一天
????????????start++;
????????}
????????return?result;
????}
}

?无重叠区间

题目

????????给定一个区间的集合?intervals?,其中 intervals[i] = [starti, endi]?。返回 需要移除区间的最小数量,使剩余区间互不重叠?。?

示例 :

????????输入: intervals = [[1,2],[2,3],[3,4],[1,3]]

????????输出: 1

????????解释: 移除 [1,3] 后,剩下的区间没有重叠。

贪心策略

? ? ? ? 如果区间之间冲突,就删除占用区间最大的那个

class?Solution?{
????public?int?eraseOverlapIntervals(int[][]?intervals)?{
????????//按照起始位置递增排序
????????Arrays.sort(intervals,?(a,b)->a[0]-b[0]);
????????int?num=0;
????????int?i=0;
????????for(int?j=1;j<intervals.length;++j){
????????????if(intervals[j][0]>=intervals[i][1]){
????????????????//区间之间不冲突
????????????????i=j;
????????????}else{
????????????????if(intervals[j][1]<intervals[i][1]){
????????????????????i=j;
????????????????}
????????????????num++;
????????????}
????????}
????????return?num;
????}
}

😀总结

🌈贪心策略

1. 建立数学模型来描述问题;

2. 把求解的问题分成若干个子问题;

3. 对每一子问题求解,得到子问题的局部最优解;

4. 把子问题的局部最优解合成原来解问题的一个解。

用白话说,即假设一个问题比较复杂,暂时找不到全局最优解,那么我们可以考虑把原问题拆成几个小问题,分别求每个小问题的最优解,再把这些“局部最优解”叠起来,就“当作”整个问题的最优解了。

🌈该算法存在的问题

不能保证求得的最后解是最佳的

不能用来求最大值或最小值的问题

只能求满足某些约束条件的可行解的范围

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-07 11:22:23  更:2022-05-07 11:23:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:26:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码