0
点赞
收藏
分享

微信扫一扫

颜色分类(数组、双指针)、排列序列(递归、数学)、合并区间(数组、排序)

颜色分类(数组、双指针)

给定一个包含红色、白色和蓝色,一共 n_ _个元素的数组,**原地(https://baike.baidu.com/item/%E5%8E%9F%E5%9C%B0%E7%AE%97%E6%B3%95)**对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

示例 1:

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

示例 2:

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

示例 3:

输入:nums = [0]
输出:[0]

示例 4:

输入:nums = [1]
输出:[1]

提示:

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

进阶:

  • 你可以不使用代码库中的排序函数来解决这道题吗?
  • 你能想出一个仅使用常数空间的一趟扫描算法吗?

解答:

class Solution {
    public void sortColors(int[] nums) {
        int low = 0, high = nums.length - 1;
        int i = 0;
        while (i <= high) {
            if (nums[i] == 0) {
                int tmp = nums[i];
                nums[i] = nums[low];
                nums[low] = tmp;
                ++low;
                ++i;
            } else if (nums[i] == 1) {
                ++i;
            } else if (i <= high && nums[i] == 2) {
                int tmp = nums[i];
                nums[i] = nums[high];
                nums[high] = tmp;
                --high;
            }
        }
    }
}

排列序列(递归、数学)

给出集合 [1,2,3,...,n],其所有元素共有 n! 种排列。 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

给定 n 和 k,返回第 k 个排列。

示例 1:

输入:n = 3, k = 3
输出:"213"

示例 2:

输入:n = 4, k = 9
输出:"2314"

示例 3:

输入:n = 3, k = 1
输出:"123"

提示:

  • 1 <= n <= 9
  • 1 <= k <= n!

以下程序实现了这一功能,请你填补空白处内容:

class Solution {
	public String getPermutation(int n, int k) {
		StringBuilder sb = new StringBuilder();
		List<Integer> candidates = new ArrayList<>();
		int[] factorials = new int[n + 1];
		factorials[0] = 1;
		int fact = 1;
		for (int i = 1; i <= n; ++i) {
			candidates.add(i);
			fact *= i;
			factorials[i] = fact;
		}
		k -= 1;
		____________________;
		return sb.toString();
	}
}

解答:

for (int i = n - 1; i >= 0; --i) {
	int index = k / factorials[i];
	sb.append(candidates.remove(index));
	k -= index * factorials[i];
}

合并区间(数组、排序)

以数组 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) {
        List<int[]> res = new ArrayList<>();
        if (intervals == null) {
            return res.toArray(new int[0][]);
        }
        Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
        int i = 0;
        int left = 0;
        int right = 0;
        while (i < intervals.length) {
            left = intervals[i][0];
            right = intervals[i][1];
            while (i < intervals.length - 1 && right >= intervals[i + 1][0]) {
                i++;
                right = Math.max(right, intervals[i][1]);
            }
            res.add(new int[] { left, right });
            i++;
        }
        return res.toArray(new int[0][]);
    }
}

本文内容到此结束了, 如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。 如有错误❌疑问💬欢迎各位大佬指出。 主页:共饮一杯无的博客汇总👨‍💻

保持热爱,奔赴下一场山海。🏃🏃🏃

举报

相关推荐

0 条评论