算法通关村第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;
        }
        
    }
}
相关推荐
Jerry1 小时前
LeetCode 28. 找出字符串中第一个匹配项的下标
算法
Jerry3 小时前
LeetCode 459. 重复的子字符串
算法
闲猫6 小时前
Spring AI 对接Deepseek ChatModel 聊天对话
java·前端·spring
海石6 小时前
1500分的题目,确实有实力,不过还是我略胜一筹
算法·leetcode
海石6 小时前
【记忆化搜索】条条大路通AC,走好适合你的那一条,走到后再考虑走得快
算法·leetcode
自信的未来7 小时前
JSON 工具|Web Worker 工程化打包 + 语法自动修复 + 多语言代码生成实战
java·前端·json
Brookty7 小时前
【JavaEE】线程安全(一).4:写块串行保安全、CAS
java·开发语言·java-ee·多线程·线程安全
Jerry8 小时前
LeetCode 151. 反转字符串中的单词
算法
怕孤单的草丛8 小时前
缓存管理面临的主要问题
java·数据库·缓存