您的位置:首页 > 其它

LeetCode 分类练习(2)—— 三向切分 partition 思想的应用

2017-11-22 23:53 501 查看

75. Sort Colors

Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

Note:
You are not suppose to use the library's sort function for this problem.


假定数组中只有 0,1,2,对此数组进行排序。

思路:



1、使用一个数组统计输入数组中 0、1 、 2 的出现次数

2、对输入数组重新赋值



1、使用三向切分的思想,将数组中的元素按照 <1、 ==1 、>1 的顺序排列

package com.leetcode.sort;

public class SortColors {
// 使用 计数排序
//    public void sortColors(int[] nums) {
//        int[] count = {0, 0, 0};
//        for (int num : nums)
//            count[num]++;
//        int index = 0;
//        int k = 0;
//        for (int n : count) {
//            while (n != 0) {
//                nums[index++] = k;
//                n--;
//            }
//            k++;
//        }
//    }
// 使用 快速排序的三向切分思想
public void sortColors(int[] nums) {
// 假设在 nums[] 的最前端加上一个 nums[-1] = 1
int lt = -1, i = 0, gt = nums.length;    // [0...lt] == 0  [gt...n-1] == 2
while (i < gt) {
if (nums[i] == 0)
swap(nums, i++, ++lt);
else if (nums[i] == 1)
i++;
else // nums[i] == 2
swap(nums, i, --gt);
}
}

public void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}

public static void main(String[] args) {
//        int[] nums = {1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0};
int[] nums = {2, 1};
SortColors sortColors = new SortColors();
sortColors.sortColors(nums);
for (int num : nums)
System.out.print(num + " ");
}

}


88. Merge Sorted Array

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.


给定两个有序数组 nums1 和 nums2,把 nums2 归并到 nums1 变为一个有序的数组

思路:

1、从 nums1 和 nums2 的尾部(有元素的位置开始),开始向前遍历,选择两者中较大的元素依次放入 nums1 的尾部(最初是空的)

2、直到两者中的任意一者中的元素用尽时

3、若此时 nums2 中还有元素,则将 nums2 中的剩余数据按序全部放入 nums1 中

class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
while(m > 0 && n > 0){
if(nums1[m-1] > nums2[n-1]){
nums1[m+n-1] = nums1[m-1];
m--;
}else{
nums1[m+n-1] = nums2[n-1];
n--;
}
}
while(n>0){
nums1[m+n-1] = nums2[n-1];
n--;
}
}
}


package com.leetcode.sort;

import java.util.Arrays;

// 88 Merge Sorted Array

public class MergeSortedArray {
// 简单的归并排序思路
public void merge(int[] nums1, int m, int[] nums2, int n) {

//        int[] aux = Arrays.copyOfRange(nums1, 0, m);
//        int i = 0, j = 0;
//        for (int k = 0; k < m + n; k++) {
//            if (i >= m) {
//                nums1[k] = nums2[j];
//                j++;
//            }else if (j >= n){
//                nums1[k] = aux[i];
//                i++;
//            }else if (aux[i] > nums2[j]) {
//                nums1[k] = nums2[j];
//                j++;
//            } else if(aux[i] <= nums2[j]){
//                nums1[k] = aux[i];
//                i++;
//            }
//        }

int i = m - 1;  // 指向 nums1[] 中数据的末尾
int j = n - 1;  // 指向 nums2[] 中数据的末尾
int k = m + n - 1;  // 指向 nums1[] 中需要写入数据的最后一个下标
while (i >= 0 && j >= 0) {
if (nums1[i] > nums2[j])
nums1[k--] = nums1[i--];
else
nums1[k--] = nums2[j--];
}
while (j >= 0)
nums1[k--] = nums2[j--];
}

// 从后向前 向 nums1[] 数组[m...m+n-1]区间内填充数据,不需要额外空间
// 即使 nums2[] 中的数据先被用尽,nums2[] 中原有的数据也是相对有序的
//    public void merge(int nums1[], int m, int nums2[], int n) {
//        int i = m - 1;  // 指向 nums1[] 中数据的末尾
//        int j = n - 1;  // 指向 nums2[] 中数据的末尾
//        int k = m + n - 1;  // 指向 nums1[] 中需要写入数据的最后一个下标
//        while (i >= 0 && j >= 0)    // 当 nums1 和 nums2 中还有数据时,向 num1[k] 中存入较大的数据
//            nums1[k--] = (nums1[i] > nums2[j]) ? nums1[i--] : nums2[j--];
//        while (j >= 0)  // 当原来 nums1[] 中的数据用尽后,将 nums2 中剩下的数据存入 nums1 中
//            nums1[k--] = nums2[j--];
//    }

public static void main(String[] args) {
int[] nums1 = {6, 7, 0, 0, 0};
int m = 2;
int[] nums2 = {2};
int n = 1;
//        int[] nums1 = {1};
//        int m = 1;
//        int[] nums2 = {};
//        int n = 0;
MergeSortedArray mergeSortedArray = new MergeSortedArray();
mergeSortedArray.merge(nums1, m, nums2, n);
for (int num : nums1)
System.out.print(num + " ");
}
}


215. Kth Largest Element in an Array

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.


找到数组中第 k 大的元素

思路:



1、应用快速排序的 partition 的思想



1、使用优先队列

package com.leetcode.sort;

// 215 FindKthLargest

public class FindKthLargest {
public int findKthLargest(int[] nums, int k) {
int n = nums.length;
return solve(nums, 0, n - 1, k-1);
}

private int solve(int[] nums, int l, int r, int target) {
int p = partition(nums, l, r);
if (p == target)
return nums[p];
else if (p > target)
return solve(nums, l, p-1, target);
else
return solve(nums, p+1, r, target);
}

private int partition(int[] nums, int l, int r) {
int temp = nums[l];
int i = l + 1, j = l;
for (; i <= r; i++) {
if (nums[i] > temp)
swap(nums, i, ++j);
}
swap(nums, l, j);
return j;
}

private void swap(int[] nums, int a, int b) {
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}

public int[] generateRandomArray(int n, int rangeL, int rangeR) {
int[] arr = new int
;
for (int i = 0; i < n; i++)
arr[i] = ((int)(Math.random() * (rangeR - rangeL + 1) + rangeL));
return arr;
}

public static void main(String[] args){
FindKthLargest findKthLargest = new FindKthLargest();
int[] nums = findKthLargest.generateRandomArray(10, 0, 30);
for (int num: nums)
System.out.print(num + " ");
System.out.println();

int target = 3;
System.out.print(findKthLargest.findKthLargest(nums, target));
System.out.println();

//        QuickSort.sort(nums);
//        for (int num: nums)
//            System.out.print(num + " ");
//        System.out.println();

}

}


public int findKthLargest(int[] nums, int k) {
Queue<Integer> queue = new PriorityQueue<>(new MyComparator());
for(int num:nums)
queue.add(num);
while (queue.size() > nums.length - k +1)
queue.remove();
return queue.peek();
}

class MyComparator implements Comparator{
@Override
public int compare(Object o1, Object o2) {
int num1 = (int) o1;
int num2 = (int) o2;
if (num1 < num2)
return 1;
else if (num1 > num2)
return -1;
return 0;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: