力扣排序练习题(合并区间、颜色分类)

122 阅读3分钟

合并区间

来源:力扣(LeetCode) 链接:leetcode.cn/problems/me…

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]

输出:[[1,6],[8,10],[15,18]]

解释:区间 [1,3][2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]

输出:[[1,5]]

解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示:

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

代码

class Solution {
    public int[][] merge(int[][] intervals) {
        // 对区间按照起始位置进行排序
        Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
        
        List<int[]> merged = new ArrayList<>();
        int[] currInterval = intervals[0];
        merged.add(currInterval);
        
        for (int[] interval : intervals) {
            int currEnd = currInterval[1];
            int nextStart = interval[0];
            int nextEnd = interval[1];
            
            if (currEnd >= nextStart) {
                // 当前区间和下一个区间有重叠,更新当前区间的结束位置
                currInterval[1] = Math.max(currEnd, nextEnd);
            } else {
                // 当前区间和下一个区间没有重叠,将下一个区间加入结果列表
                currInterval = interval;
                merged.add(currInterval);
            }
        }
        
        return merged.toArray(new int[merged.size()][]);
    }
}

思路分析

  1. 首先对给定的区间按照起始位置进行排序,以确保相邻的区间在数组中也是相邻的。

  2. 创建一个列表 merged 用于存储合并后的区间。

  3. 初始化 currInterval 为排序后的第一个区间,将其加入 merged

  4. 遍历排序后的区间数组:

    • 分别记录当前区间的结束位置 currEnd 和下一个区间的起始位置 nextStart、结束位置 nextEnd
    • 如果当前区间的结束位置大于等于下一个区间的起始位置,表示两个区间有重叠,更新当前区间的结束位置为 currEndnextEnd 中的较大值。
    • 如果当前区间和下一个区间没有重叠,将下一个区间加入结果列表 merged,并将 currInterval 更新为下一个区间。
  5. 返回合并后的区间数组 merged

颜色分类

来源:力扣(LeetCode) 链接:leetcode.cn/problems/so…

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

示例 1:

输入:nums = [2,0,2,1,1,0]

输出:[0,0,1,1,2,2]

示例 2:

输入:nums = [2,0,1]

输出:[0,1,2]

提示:

  • n == nums.length
  • 1 <= n <= 300
  • nums[i] 为 0、1 或 2

代码

class Solution {
    public void sortColors(int[] nums) {
        int n = nums.length;
        int p0 = 0; // 指向0的指针
        int p2 = n - 1; // 指向2的指针
        int curr = 0; // 当前遍历的指针
        
        while (curr <= p2) {
            if (nums[curr] == 0) {
                swap(nums, curr, p0);
                curr++;
                p0++;
            } else if (nums[curr] == 2) {
                swap(nums, curr, p2);
                p2--;
            } else {
                curr++;
            }
        }
    }
    
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

思路分析

  1. 使用三个指针 p0p2curr 分别表示0、2的位置以及当前遍历的指针。

  2. 初始化 p0 指向数组的起始位置,p2 指向数组的末尾位置,curr 指向数组的起始位置。

  3. 遍历数组:

    • 如果当前元素为0,则将其与 p0 指向的元素交换,并将 p0curr 向后移动一位。
    • 如果当前元素为2,则将其与 p2 指向的元素交换,并将 p2 向前移动一位。
    • 如果当前元素为1,则直接将 curr 向后移动一位。
  4. curr 指针超过 p2 指针时,排序完成。