简单的数组问题第二部分
题解报告LeetCode#56:合并区间
思路:
- 知识点:扫描线法
 - 按照起点排序
 - 类似问题:天际线问题
 
我们只关心最后添加进来的那个区间,因此需要用一个栈
代码:
class Solution {public int merge(int[][] intervals) {int len = intervals.length;if (len == 0) {return new int[0][0];}//按照起点排序Arrays.sort(intervals, Comparator.comparingInt(i -> i[0]));Stack<int[]> stack = new Stack<>();for (int i = 1; i < len; i++) {if (stack.peek()[1] < intervals[i][0]) {stack.push(intervals[i]);} else {//更新stack.peek()[1] = Math.max(stack.peek()[1], intervals[i][1]);}}return stack.toArray(new int[0][]);}}
题解报告LeetCode#215:数组中的最大元素
在未排序的数组中找到第 **k** 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
思路:
- 方法一:暴力解法;
 - 方法二:借助 partition 操作定位到最终排定以后索引为 
len - k的那个元素(特别注意:随机化切分元素)> 注意事项:快速排序虽然快,但是如果实现得不好,在遇到特殊测试用例的时候,时间复杂度会变得很高。如果你使用
partition的方法完成这道题,时间排名不太理想,可以考虑一下是什么问题,这个问题很常见。 
以下的描述基于”快速排序“算法知识的学习,可以复习一下 partition 过程、分治思想和“快速排序”算法的优化。
分析:我们在学习“快速排序”的时候,接触的第一个操作就是 partition ,简单介绍如下:
- 对于某个索引 
j,nums[j]已经排定,即nums[j]经过 partition (切分)操作以后会放置在它“最终应该放置的地方”; nums[left]到nums[j - 1]中的所有元素都不大于nums[j];nums[j + 1]到nums[right]中的所有元素都不小于nums[j]。

partition(切分)操作总能排定一个元素,还能够知道这个元素它最终所在的位置,这样每经过一次 partition(切分)操作就能缩小搜索的范围,这样的思想叫做 “减而治之”(是 “分而治之” 思想的特例)。
代码:
方法一:
public class Solution {
    public int findKthLargest(int[] nums, int k) {
        int len = nums.length;
        Arrays.sort(nums);
        return nums[len - k];
    }
}
方法二:
public class Solution {
    pubic int findKthLargets(int[] nums, int k) {
        int len = nums.length;
        int left = 0;
        int right = len - 1;
        //转换一下,第k大元素的索引是 len - k
        int target = len - k;
        while (true) {
            int index = partition(nums, left, right);
            if (index == target) {
                return nums[index];
            } else if (index < target) {
                left = index + 1;
            } else {
                right = index - 1;
            }
        }
    }
    public int partition(int[] nums, int left, int right) {
        int pivot = nums[left];
        int j = left;
        for (int i = left + 1; i <= right; i++) {
            if (nums[i] < pivot) {
                // 小于 pivot 的元素都被交换到前面
                j++; // 这里要记住是先 j++ 再去做交换
                swap(nums, j, i);
            }
        }
        // 在之前遍历的过程中,满足 [left + 1, j] < pivot,并且 (j, i] >= pivot
        swap(nums, j, left);
        // 交换以后 [left, j - 1] < pivot, nums[j] = pivot, [j + 1, right] >= pivot
        return j;
    }
    private void swap(int[] nums, int index1, int index2) {
        int temp = nums[index1];
        nums[index] = nums[index2];
        nums[index2] = temp;
    }
}
                    