代码随想录之贪心合集

news2025/7/17 3:52:20

455 分发饼干

在这里插入图片描述
先排序之后按顺序比较

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        //57
        Arrays.sort(g);
        Arrays.sort(s);
        int k=0;
        int i=0;
        int count=0;
        while(k<s.length&&i<g.length){
            if(g[i]<=s[k]){
                count++;
                i++;
                k++;
            }else k++;
        }

        return count;

    }
}

376 摆动序列

在这里插入图片描述
顺序查找,如果不符合一个大一个小 就继续往后找

class Solution {
    public int wiggleMaxLength(int[] nums) {
        //13
        int res = 1;
        if(nums.length==1) return nums.length;
        else if(nums.length==2&&nums[0]!=nums[1]) return 2;
        int curdiff = -1;//当前的差值
        int prediff = -1;//前一个的差值
        int f = 0;//第一次要标记,因为两个初始化都是负数
        for(int i=1;i<nums.length;i++){
            curdiff = nums[i]-nums[i-1];
            if(curdiff!=0&&f==0||curdiff>0&&prediff<0||curdiff<0&&prediff>0){
                res++;
                prediff = curdiff ;
                f = 1;
            }
        }
        return res;

    }
}

55 跳跃游戏

在这里插入图片描述
核心思想是 跳几步无所谓,关键在于可跳的覆盖范围!
不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。
这个范围内,别管是怎么跳的,反正一定可以跳过来。
那么这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!

class Solution {
    public boolean canJump(int[] nums) {
        //55
        int len = 0;
        if(nums.length==1) return true;
        for(int i=0;i<=len;i++){//注意这里是小于等于len  因为跳不到更远的地方了
            len=Math.max(len,i+nums[i]);
            if(len>=nums.length-1) return true;
        }
        return false;

    }
}

45 跳跃游戏2

在这里插入图片描述
感觉还是比较难

class Solution {
    public int jump(int[] nums) {
        //25
        //从前往后看什么时候到了最大范围
        int count = 0;
        int cover = 0; //下一步覆盖的最远距离下标
        int end = 0; // 当前覆盖的最远距离下标
        if(nums.length==1) return 0;
        for(int i=0;i < nums.length - 1;i++){
            cover = Math.max(cover,i+nums[i]);
            if(i==end){// 可达位置的改变次数就是跳跃次数
                count++;
                end = cover;//到达了上一次可达的最长位置之后,新的cover可能已经更新,不一定是最长位置向后加的
            }           
        }
        return count;

    }
}

1005 k次反转后最大化的数组和

在这里插入图片描述
在某个笔试中做过,忘记有没有全ac了,主要思路是将正数和负数分开,然后每次将负数反转,如果负数个数不够,还要判断剩下次数是偶数就不用管,因为可以对同一个元素反转多次(可能是笔试的时候题目没有强调这个),奇数的话反转绝对值最小的那个

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        //29-51
        ArrayList<Integer> pos = new ArrayList<Integer>();
        ArrayList<Integer> minus = new ArrayList<Integer>();
        int sum = 0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]>=0) pos.add(nums[i]);
            else minus.add(nums[i]);
            sum+=nums[i];
        }
        Collections.sort(pos);
        Collections.sort(minus);
        if(minus.size()>=k){
            for(int i=0;i<k;i++){
                sum = sum-2*minus.get(i);//因为原本是负的
            }
        }else{//负数不够
            for(int i=0;i<minus.size();i++){
                sum = sum-2*minus.get(i);//因为原本是负的
            }
           // System.out.println(sum);
           if((k-minus.size())%2==1){//偶数也不用管
               if(pos.size()==0){
                    sum = sum+2*minus.get(minus.size()-1);//如果有0 相当于没变化
                }else if(minus.size()==0){
                    sum = sum-2*pos.get(0);
                }else{
                    sum = sum-2*Math.min(pos.get(0),Math.abs(minus.get(minus.size()-1)));
                }
           }
            
        }
        return sum;

    }
}

134 加油站

在这里插入图片描述
改了很久,第一次的思路是找gas[i]-cost[i]最大的作为起来,然后有例子没过;第二次思路是在gas[i]-cost[i]最小的下一个作为起点,也有例子没过,后来才想起来,要找区间[]为负数的下一个,因为要尽可能让连续累加和最大的那个起始点。突然觉得这就是笔试中那些例子没过的题,如果这题没有给错误例子,估计还是改不出来

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        //22-50
        //从最多的开始出发
        int max = 0;
        int index= -1;
        int re = 0;
        for(int i=0;i<gas.length;i++){
            re+=gas[i]-cost[i];
            if(re<0){
                re = 0;
                index=i;//找到最后一个更新为0的index 要找的就是index+1
            } 
            else if(re>max){
                max = re;
            }
        }
        re = 0;
        for(int i=index+1;i<gas.length;i++){
            re+=gas[i]-cost[i];
            if(re<0) return -1;
        }
        for(int i=0;i<=index;i++){
            re+=gas[i]-cost[i];
            if(re<0) return -1;
        }
        return index+1;

    }
}

135 分糖果

在这里插入图片描述
因为几个月前做过,还是记得思路,只要从左往右比较右边比左边大,右边的就再加一个,再从右往左,左边比右边大的左边就再加一个。但是还是改了两次,第一次错在直接用sum去记录,没有用具体的数组记录每个人的糖果数量,第二次是发现要加了直接加,而不是在更少的那个基础上加。

class Solution {
    public int candy(int[] ratings) {
        //57-08
        int sum = 0;
        int[] res= new int[ratings.length];
        Arrays.fill(res,1);
        for(int i=0;i<ratings.length-1;i++){
            if(ratings[i+1]>ratings[i]&&res[i+1]<=res[i]) res[i+1]=res[i]+1;
        }
        for(int i=ratings.length-2;i>=0;i--){
            if(ratings[i+1]<ratings[i]&&res[i+1]>=res[i]) res[i]=res[i+1]+1;//要在少的基础上加,不能直接res[i]++
        }
        for(int i=0;i<res.length;i++){
            sum+=res[i];
        }
        return sum;

    }
}

860 柠檬水找零

在这里插入图片描述

class Solution {
    public boolean lemonadeChange(int[] bills) {
        //15-23
        int wu = 0;
        int shi = 0;
        int ershi = 0;
        for(int i=0;i<bills.length;i++){
            if(bills[i]==5){
                wu++;
                continue;
            }else if(bills[i] ==10){
                if(wu<=0) return false;
                wu--;
                shi++;//用5去换了
                continue;
            }
            else if(bills[i]==20){
                if(shi>=1&&wu>=1){//优先用5和10
                    shi--;
                    wu--;
                    ershi++;
                    continue;
                }else if(wu>=3){
                    wu-=3;
                    ershi++;
                    continue;
                }else return false;
            }

        }
        return true;
    }
}

406 根据身高重建队列

在这里插入图片描述
这题一开始排序没想清楚,先排了h再排身高,然后后面插入的话还会再影响前面的结果,所以一开始的思路没写出来。看了题解才知道换个排序可以简单这么多!!!就是先按照身高从大到小排序,然后再排h从小到大,这样每次从身高大的开始插入,每次插入对应的k即可!因为后面是身高更小的,对前面排好的不会产生影响!!

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        //26-17
        //插入排序 暴力
        Arrays.sort(people,(a,b)->b[0]-a[0]!=0?b[0]-a[0]:a[1]-b[1]);//身高从大到小排,k从小到大
        ArrayList<int[]> res = new ArrayList<int[]>();
        for(int[] tmp:people){
            res.add(tmp[1],tmp);
        }
        return res.toArray(new int[people.length][]);

    }
}

452 用最少数量的箭引爆气球

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

不用真的去remove,直接更新交集的右坐标,不然一开始一直想要remove的情况下思考不清楚要用什么数据结构。直接更新不用额外的数据结构。然后还有两个重要的点,也就是下面注释的两行,当数据量大到在int边界的时候不要用减号,直接判断。否则数据移除用减号判断就会出错。

class Solution {
    public int findMinArrowShots(int[][] points) {
        //交集 不用实际去模拟删除,直接更新,记录re
        int res = 1;
        if(points.length==1) return 1;
        Arrays.sort(points,(a,b)->a[0]>b[0]?1:-1);//将起始位置从小到大排序 a[0]-b[0]这样的排序在2^31时会出错
        for(int i=1;i<points.length;i++){
            if(points[i][0]<=points[i-1][1]){
                points[i][1] = Math.min(points[i][1], points[i-1][1]);//更新为交集右边界
            }else{
                res++;
            }
        }
        return res;

    }
}

435 无重叠区间

在这里插入图片描述
和上题其实是一样的,但是在写的时候遇到了排序的问题,用上一题的排序方法出出现执行错误,改成

        Arrays.sort(intervals, (a,b)-> {
            return Integer.compare(a[0],b[0]);
        });

才成功通过

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        //和上题好像一样
        //Arrays.sort(intervals,(a,b)->a[0]>b[0]?1:-1);//第二维排不排无所谓 会出现执行错误
        Arrays.sort(intervals, (a,b)-> {
            return Integer.compare(a[0],b[0]);
        });
        if(intervals.length==1) return 0;
        int res = 0;
        for(int i=1;i<intervals.length;i++){
            if(intervals[i][0]<intervals[i-1][1]){
                res++;
                intervals[i][1] = Math.min(intervals[i][1],intervals[i-1][1]);
            }
        }
        return res;
    }
}

763 划分字母区间

在这里插入图片描述

一开始打算转换成上面的区间来计算,然后越写越麻烦,还是去看了题解,get到了思路,用一个数组去记录每个字母出现的最晚的index,然后遍历这个数组,如果当前索引已经等于最大的出现过的那个索引值,就可以在这里分割

在这里插入图片描述

class Solution {
    public List<Integer> partitionLabels(String s) {
        //53
        //转换成 几个不重叠区间 会写得太麻烦
        int[] hash = new int[26]; //记录最后一个出现的index
        List<Integer> res = new ArrayList<Integer>();
        for(int i=0;i<s.length();i++){
            hash[s.charAt(i)-'a'] = i;
        }
        int max = -1;
        int index=-1;
        for(int i=0;i<s.length();i++){
            max = Math.max(max,hash[s.charAt(i)-'a']);
            if(i==max){
                res.add(max-index);
                index = i;
            }
        }

        return res;

    }
}

56 合并区间

在这里插入图片描述
一开始的思路是判断重叠就把上一个和现在的边界直接更新到原数组中,然后再判断不相等的加到res中,提交了之后发现有问题:出现两个以上需要重叠就不行,因为只能更新最近两个,更之前的就更新不到,这样就会出错。还是看了题解,换了一种添加res的方法:确定了之后不会再有重叠的之后再把之前的加入res中,这样保证每次加入的都不会在被更新,然后要记得最后一个记得添加

class Solution {
    public int[][] merge(int[][] intervals) {
        //51
        if(intervals.length==1) return intervals;  
        Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
        ArrayList<int[]> res = new ArrayList<int[]>();
        int begin = intervals[0][0];//记录上一个区间的左
        int end = intervals[0][1];//记录上一个区间的右
        for(int i=1;i<intervals.length;i++){
            if(intervals[i][0]<=end){//直接修改原数组                
                end = Math.max(intervals[i][1],end);
            }else{//直到判断到右边的不会重叠了 再把前一个加入
                res.add(new int[]{begin, end});
                begin = intervals[i][0];
                end = intervals[i][1];
            } 
        }
        res.add(new int[]{begin, end});//最后一个  
        return res.toArray(new int[res.size()][2]);
    }
}

738 单调递增的数字

在这里插入图片描述
思路很简单,就是实现起来的时候一直没写好,一开始用StringBuilder,需要各种类型的转换,没写的很清楚。思路就是从右开始找第一个左边比右边大的,找到了就把该位的数字减1,一旦减了,后面的所有数字都要改成9

class Solution {
    public int monotoneIncreasingDigits(int n) {
        //21
        if(n<=9) return n;
        //用stringbuiler写了半天 
        String s = n+"";
        char[] arr = s.toCharArray();
        int index = arr.length;//从index开始全改为9
        for(int i=arr.length-2;i>=0;i--){
            if(arr[i]>arr[i+1]){
                arr[i]--; //char可以直接-- 而且不会是0
                index = i+1;
            }
        }
        for(int i=index;i<arr.length;i++){
            arr[i] = '9';
        }
        return Integer.parseInt(String.valueOf(arr));//先把char[]转为String 再转为int
    }
}

968 监控二叉树

在这里插入图片描述

摄像头可以覆盖上中下三层,如果把摄像头放在叶子节点上,就浪费的一层的覆盖。

所以把摄像头放在叶子节点的父节点位置,才能充分利用摄像头的覆盖面积。
为啥要从叶子节点看呢?因为头结点放不放摄像头也就省下一个摄像头, 叶子节点放不放摄像头省下了的摄像头数量是指数阶别的。

所以我们要从下往上看,用后序遍历!!局部最优:让叶子节点的父节点安摄像头,所用摄像头最少,整体最优:全部摄像头数量所用最少!

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int res = 0;
    public int minCameraCover(TreeNode root) {
        if(af(root)==0){
            res++;
        }
        return res;

    }
    //  0 表示无覆盖
    //   1 表示 有摄像头
    //   2 表示有覆盖
    public int af(TreeNode root){
        if(root==null) return 2;//空节点要默认为有覆盖,防止在叶子节点放
        int left = af(root.left);
        int right = af(root.right);
        if(left==2&&right==2){
            return 0;//左右都被覆盖 父节点无覆盖
        }else if(left==0||right==0){
            res++;
            return 1;
        }else return 2;
    }
}

有注释:

class Solution {
    int  res=0;
    public int minCameraCover(TreeNode root) {
        // 对根节点的状态做检验,防止根节点是无覆盖状态 .
        if(minCame(root)==0){
            res++;
        }
        return res;
    }
    /**
     节点的状态值:
       0 表示无覆盖
       1 表示 有摄像头
       2 表示有覆盖
    后序遍历,根据左右节点的情况,来判读 自己的状态
     */
    public int minCame(TreeNode root){
        if(root==null){
            // 空节点默认为 有覆盖状态,避免在叶子节点上放摄像头
            return 2;
        }
        int left=minCame(root.left);
        int  right=minCame(root.right);

        // 如果左右节点都覆盖了的话, 那么本节点的状态就应该是无覆盖,没有摄像头
        if(left==2&&right==2){
            //(2,2)
            return 0;
        }else if(left==0||right==0){
            // 左右节点都是无覆盖状态,那 根节点此时应该放一个摄像头
            // (0,0) (0,1) (0,2) (1,0) (2,0)
            // 状态值为 1 摄像头数 ++;
            res++;
            return 1;
        }else{
            // 左右节点的 状态为 (1,1) (1,2) (2,1) 也就是左右节点至少存在 1个摄像头,
            // 那么本节点就是处于被覆盖状态
            return 2;
        }
    }
}

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

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

相关文章

视频大文件传输的演变:从“卷轴男孩”到自动化

200年前&#xff0c;从纽约市到英国伦敦的单程旅行需要乘坐一艘跨大西洋轮船将近三周——如果你能负担得起的话&#xff0c;那就是。那些不能在满是汗水、狭窄的帆船上安顿大约一个半月的人。 今天&#xff0c;视频专业人士能够在几小时甚至几分钟内跨越相同的物理距离传输大量…

烟雾弹?突然转变?如何看待微软发声:中国是主要的对手

是的&#xff0c;我又回来了&#xff0c;今天要跟各位唠的还是ChatGPT的嗑。今天的新闻是啥呢&#xff1f; 《微软总裁&#xff1a;中国将是 ChatGPT 的主要对手&#xff0c;我们的优势不大》 说实话&#xff0c;我看到这个新闻的时候&#xff0c;大感震撼&#xff0c;在相关报…

YOLOv5快速入门demo

文章目录 1. 官网下载 yolo_master2. 下载得到yolov5-maser.zip 对其进行解压3. 安装所需要的包4. 官网下载一个与训练模型5. 测试一个小demo 使用detect.py6. 训练一个模型 1. 官网下载 yolo_master https://gitcode.net/mirrors/ultralytics/yolov5 下载克隆 2. 下载得到…

HART协议数据格式避坑(C语言压缩字符串Packed-ASCII和ASCII转换)

HART协议数据格式避坑&#xff08;C语言压缩字符串Packed-ASCII和ASCII转换&#xff09; 首先HART数据格式如下&#xff1a; 重点就是浮点数和字符串类型 Latin-1就不说了 基本用不到 浮点数 浮点数里面 如 0x40 80 00 00表示4.0f 在HART协议里面 浮点数是按大端格式发送的…

oracle 18c dataguard 从库scn 不更新BUG

Bug 29056767 - STANDBY: Datafiles Checkpoint not Updated at Standby Database when Media Recover is running (Doc ID 29056767.8)正在上传…重新上传取消To Bottom Bug 29056767 STANDBY: Datafiles Checkpoint not Updated at Standby Database when Media Recover i…

IPEmotion控制模块-PID循环应用

IPEmotion专业版、开发版支持控制模块&#xff0c;并且该模块支持函数发生器、PID控制器、路由器、序列控制和序列控制块以及参考曲线生成器。本文主要针对PID&#xff08;P&#xff1a;Proportional control 比例控制&#xff1b;I&#xff1a;Integral control 积分控制&…

Linux tail 命令

前言 Linux 实时查看日志文件&#xff0c;最主要使用的就是tail命令。 linux tail命令用于显示文件尾部的内容&#xff0c;默认在屏幕上显示指定文件的末尾10行。如果给定的文件不止一个&#xff0c;则在显示的每个文件前面加一个文件名标题。如果没有指定文件或者文件名为“-”…

同步辐射全散射PDF分析:探究材料结构的新方法

同步辐射全散射PDF&#xff08;Pair Distribution Function&#xff09;分析是一种非常强大的物质结构研究方法。它通过同步辐射技术&#xff0c;将X射线或中子散射的数据进行处理&#xff0c;得到物质的原子间距分布函数&#xff0c;从而揭示物质的微观结构信息。该方法已经在…

Vue3上传(Upload)

可自定义设置以下属性&#xff1a; 接受上传的文件类型&#xff08;accept&#xff09;&#xff0c;类型&#xff1a;string&#xff0c;默认 *&#xff0c;&#xff0c;与<input type"file">的accept属性一致&#xff0c;详见 https://developer.mozilla.org/…

数据结构与算法(五):算法专项 Hash、BitMap、Set、布隆过滤器、中文分词、Lucene 倒排索引

算法专项 Hash、BitMap、Set、布隆过滤器、中文分词、Lucene 倒排索引 Hash 思考&#xff1a; 给你N&#xff08;1<N<10&#xff09;个自然数,每个数的范围为&#xff08;1~100&#xff09;。现在让你以最快的速度判断某一个数是否在这N个数内&#xff0c;不得使用已经…

Ubuntu20.04+安装MySQL8+ 并设置忽略表名大小写

更新apt apt -y update安装mysql-server apt -y install mysql-server查看服务是否启动 ps -ef | grep mysql如下图启动成功 或者 systemctl status mysql设置root登录密码 执行命令&#xff1a; mysql -uroot选择数据库&#xff1a; use mysql;修改密码&#xff1a; a…

0602基础使用(一)-react路由-react

文章目录 1 基本使用1.1 安装js库1.2 使用示例1.3 总结 2 路由组件与一般组件2.1 路由组件2.2 路由组件与普通组件示例2.3 总结 3 NavLink组件3.1 NavLink 简介3.2 NavLink实现高亮与自定义样式 结语 1 基本使用 1.1 安装js库 react-router-dom&#xff0c;react的一个插件库…

flink on k8s提交任务

目录 相关文档前置准备构建镜像提交任务 相关文档 https://nightlies.apache.org/flink/flink-docs-release-1.13/docs/deployment/resource-providers/native_kubernetes/ 前置准备 flink的lib目录下放入两个依赖 bcpkix-jdk15on-1.68.jar bcprov-jdk15on-1.69.jar 创建用户…

Vue过滤器的基本使用

过滤器 功能&#xff1a;对要显示的数据进行特定格式化后再显示 注意&#xff1a;并没有改变原本的数据&#xff0c;是产生新的对应的数据 声明&#xff1a;过滤器不是必须要用到的东西&#xff0c;而是vue提供处理数据的方式而已&#xff0c;想用就用&#xff0c;不想用可以…

Elasticsearch 实战篇 | 黑马旅游

一、酒店搜索和分页 需求&#xff1a;实现黑马旅游的酒店搜索功能&#xff0c;完成关键字搜索和分页 1、定义实体类&#xff0c;接收前端的参数 如果当搜索条件为空的时候&#xff0c;就返回全部数据&#xff0c;不为空才按照key来搜索 二、条件过滤 修改实体类&#xff0c;…

边缘计算开源项目解读-kubeedge metamanager实现

0 背景 笔者在前面的几篇文章从设备管理和运维的角度解读了kubeedge的相关代码流程和架构。本文将切入kubeedge edgecore的另一个核心业务&#xff0c;即边云协同处理设备元数据相关代码的解读。如果说前面的设备管理和运维并不能体现kubeedge作为边缘计算数据处理平台的特点&a…

【Andoroid】之【APK瘦身】

一、如何查看 APK 的组成 如果要优化 APK 的大小&#xff0c;我们首先需要知道我们编译出来的 APK 都包含哪些东西&#xff0c;然后针对占用大的做裁剪&#xff0c;或者删除不需要的东西&#xff0c;从而达到瘦身的目的。 查看 APK 的内容占用情况很简单&#xff0c;打开 AS …

进程间通信,有名管道(pipe)与无名管道(fifo)的解析与运用,以及代码实现

&#x1f38a;【进程通信与并发】专题正在持续更新中&#xff0c;进程&#xff0c;线程&#xff0c;IPC&#xff0c;线程池等的创建原理与运用✨&#xff0c;欢迎大家前往订阅本专题&#xff0c;获取更多详细信息哦&#x1f38f;&#x1f38f;&#x1f38f; &#x1fa94;本系列…

API网关:开源Apinto网关-应用管理篇

需求痛点 在这互联网高速发展的时代&#xff0c;企业业务系统多、渠道广&#xff0c;如何管理内外部调用端系统具有极大的挑战。 数量方面&#xff1a;API网关需要对各端应用统一管理&#xff0c;例如对企业自身很多的前端应用&#xff0c;包括不限于web应用、移动APP、小程序&…

AI边缘计算智能分析网关灭火器缺失检测与告警的实现过程

AI智能分析网关基于边缘智能&#xff0c;部署了多种AI深度学习算法&#xff0c;可对接入的多路视频流进行智能检测、智能识别等&#xff0c;包括人脸检测与识别、车辆检测与识别、车牌识别、烟火识别、安全帽识别、区域入侵检测等。今天我们来介绍下关于灭火器缺失检测与告警的…