代码随想录-2023/08/02

109 阅读1分钟

贪心算法

435.无重叠区间

解题思路:

重叠区间套路题: 从下标为1的位置开始比较重叠情况, 并进行处理

  1. 若无重叠, 则应当使用新区间向后比较
  2. 若有重叠区间, 则应该删除右端点值较大的区间, 使用右端点值较小的区间去向后比较, 这样能防止更多的重叠区间

代码:

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals, (c1,c2)->c1[0]-c2[0]);
        // 从第二个元素开始判断是否有重叠区间
        LinkedList<int[]> list = new LinkedList<>();
        int ans = 0;
        list.add(intervals[0]);
        for(int i=1; i<intervals.length; i++) {
            int[] pre = list.getLast();
            // 无重叠
            if(pre[1] <= intervals[i][0]){
                list.add(intervals[i]);
            }else {
                // 判断重叠情况, 若包含当前区间, 应当将pre设置为当前区间
                // 若不包含当前区间, 应当删除的是当前区间, 因为其能防止后面的包含
                if(pre[1] > intervals[i][1]) {
                    list.add(intervals[i]); 
                }
                // 有重叠就至少需要移除一个
                ans++;
            }
        }
        return ans;
    }
}

763.划分字母区间

解题思路:

  1. 先用一个哈希表统计每个字符最后出现的位置
  2. 从头开始遍历, 在遍历过程中不断更新遍历终点为当前区间中字符出现的最远位置
  3. 遍历到最后, 若遍历位置等于其前面所有字符出现的最远位置, 则代表该位置之前的区间可以划分为一个区间

代码:

class Solution {
    public List<Integer> partitionLabels(String s) {
        // 统计当前字符最后一次出现的位置
        HashMap<Character, Integer> map = new HashMap<>();
        char[] ch = s.toCharArray();
        for(int i=0; i<ch.length; i++) {
            map.put(ch[i], i);
        }
        List<Integer> list = new ArrayList<>();
        int start = 0, end = map.get(ch[0]);
        while(start < ch.length) {
            int i = start;
            end = map.get(ch[start]);
            for(i = start; i<=end; i++) {
                end = Math.max(end, map.get(ch[i]));
            }
            list.add(i - start);
            start = i;
        }

        return list;
    }
}

56.合并区间

解题思路: 合并区间套路题

  1. 用list收集重叠区间, 从下标1开始, 对每个区间都和前一个区间进行合并

代码:

class Solution {
    public int[][] merge(int[][] intervals) {
        // 先排序
        Arrays.sort(intervals, (c1,c2)->c1[0]-c2[0]);
        // 合并区间到list, 组后再转为二维数组
        LinkedList<int[]> list = new LinkedList<>();
        list.add(intervals[0]);
        for(int i=1; i<intervals.length; i++) {
            int[] pre = list.getLast();
            // 没有重叠区间
            if(pre[1] < intervals[i][0]) {
                list.add(intervals[i]);
            }else {
                list.removeLast();
                list.add(new int[]{Math.min(pre[0], intervals[i][0]), Math.max(pre[1], intervals[i][1])});
            }
        }

        return list.toArray(new int[list.size()][]);

    }
}