算法通关村第17关【白银】| 贪心高频问题

区间问题

1. 会议室(判断区间是否重叠)

思路:很容易理解一个人不可能同时出席两场会议,也就是会议时间不能重叠。先按照开始时间排序,逐个比较下一个会议开始时间是否大于前一个会议的结束时间

java 复制代码
public static boolean canAttendMeetings(int[][] intervals) {
        // 将区间按照会议开始实现升序排序
        Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]);
        // 遍历会议,如果下一个会议在前一个会议结束之前就开始了,返回 false。
        for (int i = 1; i < intervals.length; i++) {
            if (intervals[i][0] < intervals[i - 1][1]) {
                return false;
            }
        }
        return true;
    }

2. 合并区间

思路:合并有重叠的区间然后加入结果集,就是需要注意一些边界

java 复制代码
class Solution {
    public int[][] merge(int[][] intervals) {
        if(intervals.length==1){
            return intervals;
        }
        Arrays.sort(intervals,(v1,v2)->v1[0]-v2[0]);
        ArrayList<int[]> list = new ArrayList<int[]>();
        int i = 1;
        while(i<intervals.length){
            if(intervals[i-1][1]<intervals[i][0]){
                list.add(intervals[i-1]);
                i++;
            }
            int k = i-1;
            while(i<intervals.length&&intervals[k][1]>=intervals[i][0]){
                intervals[k][1] = Math.max(intervals[i][1],intervals[k][1]);
                i++;
            }
            i++;
            list.add(intervals[k]);
            if(i == intervals.length){
                list.add(intervals[i-1]);
            }
        }
        return list.toArray(new int[list.size()][]);
    }
}

3. 插入区间

思路:无重复区间直接添加进结果集,重复的进行区间合并(左取小,右取大)

java 复制代码
class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        int left = newInterval[0];
        int right = newInterval[1];
        boolean placed = false;
        List<int[]> ansList = new ArrayList<int[]>();
        for (int[] interval : intervals) {
            if (interval[0] > right) {
                // 在插入区间的右侧且无交集
                if (!placed) {
                    ansList.add(new int[]{left, right});
                    placed = true;                    
                }
                ansList.add(interval);
            } else if (interval[1] < left) {
                // 在插入区间的左侧且无交集
                ansList.add(interval);
            } else {
                // 与插入区间有交集,计算它们的并集
                left = Math.min(left, interval[0]);
                right = Math.max(right, interval[1]);
            }
        }
        if (!placed) {
            ansList.add(new int[]{left, right});
        }
        int[][] ans = new int[ansList.size()][2];
        for (int i = 0; i < ansList.size(); ++i) {
            ans[i] = ansList.get(i);
        }
        return ans;
    }
}

字符串分割

思路:很容易想到首先遍历一遍获得每个字母的最后出现的下标位置,怎么找出包含当前字母最后一次出现的最短的片段呢?也就是在第二次遍历中:当前遍历的位置正好是前面所有字母中最长的end位置

java 复制代码
class Solution {
    public List<Integer> partitionLabels(String s) {
        int[] last = new int[26];
        int len = s.length();
        for(int i = 0;i<len;i++){
            last[s.charAt(i)-'a'] = i;
        }
        int end = 0;
        List<Integer> list = new ArrayList<Integer>();
        int start = 0;
        for(int i = 0;i<len;i++){
            //当前字母的end是最后的end
            end = Math.max(last[s.charAt(i)-'a'],end);
            if(i == end){
                list.add(i - start + 1);
                start = end+1;
            }
        }
        return list;
    }
}

加油站

思路:如果每个加油站的剩余油量总和大于等于0那么就是能跑完全程,当前剩余油量小于零则不能从i之前的加油站出发,剩余总油量固定左边小右边就大

java 复制代码
class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int total = 0;
        int cur = 0;
        int start = 0;
        for(int i = 0;i<gas.length;i++){
            total += gas[i] - cost[i];
            cur += gas[i] - cost[i];
            if(cur<0){
                start = i + 1;
                cur = 0;
            }
        }
        if(total<0){
            return -1;
        }else{
            return start;
        }
        
    }
}
相关推荐
Fuxiao___3 小时前
C 语言核心知识点讲义(循环 + 函数篇)
算法·c#
lifewange3 小时前
java连接Mysql数据库
java·数据库·mysql
漫随流水4 小时前
c++编程:反转字符串(leetcode344)
数据结构·c++·算法
云原生指北4 小时前
命令行四件套:fd-rg-fzf-bat
java·大数据·elasticsearch
人间打气筒(Ada)5 小时前
go实战案例:如何通过 Service Meh 实现熔断和限流
java·开发语言·golang·web·istio·service mesh·熔断限流
穿条秋裤到处跑5 小时前
每日一道leetcode(2026.03.31):字典序最小的生成字符串
算法·leetcode
主宰者6 小时前
C# CommunityToolkit.Mvvm全局事件
java·前端·c#
计算机学姐6 小时前
基于SpringBoot的咖啡店管理系统【个性化推荐+数据可视化统计+配送信息】
java·vue.js·spring boot·后端·mysql·信息可视化·tomcat
My的梦想已实现6 小时前
关于JAVA Springboot集成支付后打包JAR之后报安全错误的处理
java·spring boot·jar
ooseabiscuit6 小时前
SpringBoot3整合FastJSON2如何配置configureMessageConverters
java