- 数组中的第K个最大元素
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
class Solution {
public int findKthLargest(int[] nums, int k) {
return SortUtil.quickSelect(nums,0,nums.length-1,nums.length-k);
}
static class SortUtil {
static void quickSort(int[] p, int i, int j) {
if (j <= i) return;
int pivotIndex = ThreadLocalRandom.current().nextInt(i, j + 1);
int pivot = p[pivotIndex];
swap(p, i, pivotIndex);
int p1 = i, p2 = j;
while (p1 < p2) {
while (p1 < p2 && p[p2] >= pivot) {
p2--;
}
while (p1 < p2 && p[p1] <= pivot) {
//p1 跑太过了,导致 p1>=p2 但是, p[p2] >= pivot ,所以,排序不正确,因此,必须要保证 p[p2] >= pivot ,p2跑到最左边
p1++;
}
if (p1 < p2) {
swap(p, p1, p2);
}
// System.out.println(Arrays.toString(p)+ " :"+p1+" "+p2);
}
swap(p, i, p1);
quickSort(p, i, p1 - 1);
quickSort(p, p1 + 1, j);
}
static void swap(int[] p, int i, int j) {
int t = p[j];
p[j] = p[i];
p[i] = t;
}
static void findK(int[] p, int i, int j, int k) {
if (j <= i) return;
int p1 = partition(p,i,j);
if(p1==k-1) {
//找到了
return;
}else if(p1<k-1) {
//往右边找
findK(p,p1+1,j,k);
}else {
//往左边找
findK(p,i,p1-1,k);
}
}
static int partition(int[]p,int i,int j) {
int pivotIndex = ThreadLocalRandom.current().nextInt(i, j + 1);
int pivot = p[pivotIndex];
int p1 = i, p2 = j;
swap(p, p1, pivotIndex);
while (p1 < p2) {
while (p1 < p2 && p[p2] >= pivot) {
--p2;
}
while (p1 < p2 && p[p1] <= pivot) {
++p1;
}
if (p1 < p2) swap(p, p1, p2);
}
swap(p, p1, i);
return p1;
}
static int quickSelect(int []p,int l,int r,int index) {
int pivot = partition(p,l,r);
if(index==pivot) return p[pivot];
else
{
return pivot<index? quickSelect(p,pivot+1,r,index):
quickSelect(p,l,pivot-1,index);
}
}
}
}
- 最接近原点的 K 个点
我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。
(这里,平面上两点之间的距离是欧几里德距离。)
你可以按任何顺序返回答案。除了点坐标的顺序之外,答案确保是唯一的。
import java.util.concurrent.ThreadLocalRandom;
class Solution {
int[][] points;
public int[][] kClosest(int[][] points, int K) {
this.points = points;
SortUtil.findK(points,0,points.length-1,K-1);
return Arrays.copyOfRange(points, 0, K);
}
static class SortUtil {
static void quickSort(int[] p, int i, int j) {
if (j <= i) return;
int pivotIndex = ThreadLocalRandom.current().nextInt(i, j + 1);
int pivot = p[pivotIndex];
swap(p, i, pivotIndex);
int p1 = i, p2 = j;
while (p1 < p2) {
while (p1 < p2 && p[p2] >= pivot) {
p2--;
}
while (p1 < p2 && p[p1] <= pivot) {
//p1 跑太过了,导致 p1>=p2 但是, p[p2] >= pivot ,所以,排序不正确,因此,必须要保证 p[p2] >= pivot ,p2跑到最左边
p1++;
}
if (p1 < p2) {
swap(p, p1, p2);
}
// System.out.println(Arrays.toString(p)+ " :"+p1+" "+p2);
}
swap(p, i, p1);
quickSort(p, i, p1 - 1);
quickSort(p, p1 + 1, j);
}
static void swap(int[] p, int i, int j) {
int t = p[j];
p[j] = p[i];
p[i] = t;
}
public static void swap(int[][]points,int i, int j) {
int t0 = points[i][0], t1 = points[i][1];
points[i][0] = points[j][0];
points[i][1] = points[j][1];
points[j][0] = t0;
points[j][1] = t1;
}
static void findK(int[][] p, int i, int j, int index) {
if (j <= i) return;
int p1 = partition(p,i,j);
if(p1==index) {
//找到了
return;
}else if(p1<index) {
//往右边找
findK(p,p1+1,j,index);
}else {
//往左边找
findK(p,i,p1-1,index);
}
}
static int len(int[][]p,int i) {
return p[i][0]*p[i][0]+
p[i][1]*p[i][1];
}
static int partition(int[][]p,int i,int j) {
int pivotIndex = ThreadLocalRandom.current().nextInt(i, j + 1);
int pivot = len(p,pivotIndex);
int p1 = i, p2 = j;
swap(p, p1, pivotIndex);
while (p1 < p2) {
while (p1 < p2 && /*p[p2]*/len(p,p2) >= pivot) {
--p2;
}
while (p1 < p2 && len(p,p1) <= pivot) {
++p1;
}
if (p1 < p2) swap(p, p1, p2);
}
swap(p, p1, i);
return p1;
}
// static int quickSelect(int[]p,int l,int r,int index) {
// int pivot = partition(p,l,r);
// if(index==pivot){
// return p[pivot];
// }
// else
// {
// return pivot<index? quickSelect(p,pivot+1,r,index):
// quickSelect(p,l,pivot-1,index);
// }
// }
}
}