Find the k-k-big or small questions, but also often interview test, to sum up here;
First quick select the template to be memorized algorithm, this algorithm is refined by quick sort inside; a if, the same condition two while; then followed by recursive
Kth Smallest Numbers in Unsorted Array
Find a disordered array of small numbers of K
Example
Example 1:
输入: [3, 4, 1, 2, 5], k = 3
输出: 3
Sample 2:
输入: [1, 1, 1], k = 2
输出: 1
Thinking: quickselect Standard Solution: O (N);
public class Solution {
/**
* @param k: An integer
* @param nums: An integer array
* @return: kth smallest element
*/
public int kthSmallest(int k, int[] nums) {
if(nums == null || nums.length == 0 || k <= 0){
return -1;
}
return quickselect(nums, k, 0, nums.length - 1);
}
private int quickselect(int[] nums, int k, int start, int end) {
if(start == end) {
return nums[start];
}
int mid = start + (end - start) / 2;
int pivot = nums[mid];
int i = start; int j = end;
while(i <= j) {
while(i <= j && nums[i] < pivot) {
i++;
}
while(i <= j && nums[j] > pivot) {
j--;
}
if(i <= j) {
swap(nums, i, j);
i++;
j--;
}
}
if(start + k - 1 <= j) {
return quickselect(nums, k, start, j);
}
if(start + k - 1 >= i) {
return quickselect(nums, k - (i -start), i, end);
}
return nums[j+1];
}
private void swap(int[] A, int i, int j) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
Kth Largest Element
Find the k-th largest element in the array.
Example
Example 1:
输入:
n = 1, nums = [1,3,4,2]
输出:
4
Ideas: the first is to find descending k large; the idea is the same with the above, quick select a template to go from;
public class Solution {
/**
* @param n: An integer
* @param nums: An array
* @return: the Kth largest element
*/
public int kthLargestElement(int n, int[] nums) {
if(nums == null || nums.length == 0 || n <= 0){
return -1;
}
return quickselect(nums, n, 0, nums.length - 1);
}
private int quickselect(int[] nums, int k, int start, int end) {
if(start == end) {
return nums[start];
}
int mid = start + (end - start) / 2;
int pivot = nums[mid];
int i = start; int j = end;
while(i <= j) {
while(i <= j && nums[i] > pivot) {
i++;
}
while(i <= j && nums[j] < pivot) {
j--;
}
if(i <= j) {
swap(nums, i, j);
i++;
j--;
}
}
if(start + k - 1 <= j) {
return quickselect(nums, k, start, j);
}
if(start + k - 1 >= i) {
return quickselect(nums, k - (i -start), i, end);
}
return nums[j+1];
}
private void swap(int[] A, int i, int j) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
Kth Smallest Element in a Sorted Matrix
Given a nxn matrix, each row and each column are sorted in ascending order, find the k-th matrix element small.
Note that you need to find all the elements of the k-ordered small element, but not the first k mutually different elements.
Example
Sample 1
输入:
[[ 1, 5, 9],[10, 11, 13],[12, 13, 15]]
8
输出: 13
Ideas: here is the heap with priorityqueue to achieve log (k) to find the maximum and minimum; Comparator to write, recite every word, then pq usage is the basic test method, this problem is to send almost sub-themes; O (klogk)
public class Solution {
/**
* @param matrix: List[List[int]]
* @param k: a integer
* @return: return a integer
*/
private class Node {
public int x;
public int y;
public int value;
public Node(int x, int y, int value) {
this.x = x;
this.y = y;
this.value = value;
}
}
private class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node a, Node b) {
return (a.value - b.value);
}
}
public int kthSmallest(int[][] A, int k) {
if(A == null || A.length == 0 || A[0].length == 0 || k <= 0){
return 0;
}
int[] dx = {0, 1};
int[] dy = {1, 0};
int n = A.length;
int m = A[0].length;
PriorityQueue<Node> pq = new PriorityQueue<Node>(n*m, new NodeComparator());
boolean[][] visited = new boolean[n][m];
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
visited[i][j] = false;
}
}
pq.add(new Node(0 , 0, A[0][0]));
visited[0][0] = true;
int count = 0;
while(!pq.isEmpty()){
Node node = pq.poll();
count++;
if(count == k) {
return node.value;
}
int x = node.x;
int y = node.y;
for(int i = 0; i < dx.length; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if((0 <= nx && nx < n && 0 <= ny && ny < m && !visited[nx][ny])){
pq.add(new Node(nx, ny, A[nx][ny]));
visited[nx][ny] = true;
}
}
}
return -1;
}
}
Kth Smallest Sum In Two Sorted Arrays
Given two sorted array A , B , definition of a set of sum = a + B , A from the array where a, b from array B, seeking sum of the k-th smaller elements
Example
Sample 1
输入:
a = [1, 7, 11]
b = [2, 4, 6]
k = 3
输出: 7
说明: 满足条件的所有的和有[3, 5, 7, 9, 11, 13, 13, 15, 17],其中第三个是7.
Ideas: This title the two sort array elements in each row with each column add about
1+2, 1+4, 1+6
7+2, 7+4, 7+6
11 + 2, 4 + 11, 11 + 6, then this problem is increasing from left to right, top to bottom is incremented, it becomes a problem to completely above problem; Code edges do not need number, matrix [i] [j] = A [i] + A [j]; O (klogk)
public class Solution {
/**
* @param A: an integer arrays sorted in ascending order
* @param B: an integer arrays sorted in ascending order
* @param k: An integer
* @return: An integer
*/
private class Node {
public int x;
public int y;
public int value;
public Node(int x, int y, int value) {
this.x = x;
this.y = y;
this.value = value;
}
}
private class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node a, Node b) {
return (a.value - b.value);
}
}
public int kthSmallestSum(int[] A, int[] B, int k) {
if(A == null || A.length == 0 || B == null || B.length == 0 || k <= 0){
return -1;
}
int[] dx = {0, 1};
int[] dy = {1, 0};
int n = A.length;
int m = B.length;
PriorityQueue<Node> pq = new PriorityQueue<Node>(n*m, new NodeComparator());
boolean[][] visited = new boolean[n][m];
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
visited[i][j] = false;
}
}
pq.add(new Node(0 , 0, A[0] + B[0]));
visited[0][0] = true;
int count = 0;
while(!pq.isEmpty()){
Node node = pq.poll();
count++;
if(count == k) {
return node.value;
}
int x = node.x;
int y = node.y;
for(int i = 0; i < dx.length; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if((0 <= nx && nx < n && 0 <= ny && ny < m && !visited[nx][ny])){
pq.add(new Node(nx, ny, A[nx] + B[ny]));
visited[nx][ny] = true;
}
}
}
return -1;
}
}
Kth Largest in N Arrays
Find the big K element in the array of N
Example
Example 1:
输入:
k = 3, [[9,3,2,4,7],[1,2,3,4,8]]
输出:
7
解释:
第三大的元素为 7。
Thinking: Here the title suggests, can only swap array elements inside, then that array will be very large, it becomes impossible to combine with the quick select to do, you can only sort each array, and then do with maxheap; two Note: after 1 array sort, can be taken from the tail, that is, taking the maximum; 2 ny can be reduced to zero...
public class Solution {
/**
* @param arrays: a list of array
* @param k: An integer
* @return: an integer, K-th largest element in N arrays
*/
private class Node {
public int x;
public int y;
public int value;
public Node(int x, int y, int value) {
this.x = x;
this.y = y;
this.value = value;
}
}
private class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node a, Node b) {
return (b.value - a.value);
}
}
public int KthInArrays(int[][] arrays, int k) {
if(arrays == null || arrays.length == 0 || k <= 0){
return -1;
}
int n = arrays.length;
for(int i = 0; i < n; i++) {
Arrays.sort(arrays[i]);
}
PriorityQueue<Node> pq = new PriorityQueue<Node>(n, new NodeComparator());
for(int i = 0; i < n; i++) {
if(arrays[i].length != 0) {
int j = arrays[i].length - 1;
pq.offer(new Node(i, j, arrays[i][j]));
}
}
int count = 0;
while(!pq.isEmpty()) {
Node node = pq.poll();
count++;
if(count == k) {
return node.value;
}
int nx = node.x;
int ny = node.y - 1;
if(ny >= 0) { // 注意这里y是可以==0的;
pq.offer(new Node(nx, ny, arrays[nx][ny]));
}
}
return -1;
}
}