龙空技术网

字节面试原题:超级高频题!215. 数组中的第K个最大元素

外企小码农 92

前言:

眼前兄弟们对“n元数组所构成的空间的基”大约比较讲究,咱们都想要分析一些“n元数组所构成的空间的基”的相关知识。那么小编也在网上网罗了一些关于“n元数组所构成的空间的基””的相关知识,希望兄弟们能喜欢,朋友们快快来学习一下吧!

优化:增加pivot的随机性可以让算法更加稳定

解法:快排基础上微改代码

先手写快排代码

    //快排核心    private int quickSort(int[] nums, int start, int end){        //这里没有写递归终止条件,这题不是要递归排序        int i = start;        int j = end;        int pivot = nums[start]; //选择第一个为锚点元素        while(i < j){            while(i < j && nums[j] >= pivot){                j--;            }            while(i < j && nums[i] <= pivot){                i++;            }           //交换元素         //    swap(nums, i, j)   ; //用这个没有全部通过,bug            int temp = nums[i];            nums[i] = nums[j];            nums[j] = temp;        }        //交换锚点元素至临界位置        // swap(nums, start, j);用这个没有全部通过,bug        nums[start] = nums[j];        nums[j] = pivot;        return i;               //继承递归;        // quickSort(nums, start, i-1);        // quickSort(nums, i+1, end);    }}
快排思想

两个指针,left,指向第一个,right,指最后一个。向中间靠拢,右边找比锚点元素小的值,左边找比锚点元素大的值。找到了,让这个两个值交换位置,直到left == right , 这个时候把锚点元素和left的值交换。这样锚点元素左边 都是比他小的, 右边都是比他大的

上面的返回值是int 就是我们要找的第k 大吗,不是。返回的只是随机的一个位置。这个时候利用二分查找。

int resIndex = quickSort(nums, start, end);

if(resIndex == kTarget){

return nums[resIndex];

}else if(resIndex > kTarget){

end = resIndex - 1;

}else if(resIndex < kTarget){

start = resIndex + 1;

}

全部代码:

时间复杂度:O(N),N 是数组的长度

空间复杂度:O(1),没有借助额外的空间。

class Solution {    public int findKthLargest(int[] nums, int k) {        //                 int start = 0, end = nums.length - 1;        int kTarget = nums.length - k;        while(true){            int resIndex = quickSort(nums, start, end);            if(resIndex == kTarget){                return nums[resIndex];            }else if(resIndex > kTarget){                end = resIndex - 1;            }else if(resIndex < kTarget){                start = resIndex + 1;            }        }    }    //快排核心    private int quickSort(int[] nums, int start, int end){        //这里没有写递归终止条件,这题不是要递归排序        int i = start;        int j = end;        int pivot = nums[start]; //选择第一个为锚点元素        while(i < j){            while(i < j && nums[j] >= pivot){                j--;            }            while(i < j && nums[i] <= pivot){                i++;            }           //交换元素         //    swap(nums, i, j)   ; //用这个没有全部通过,bug            int temp = nums[i];            nums[i] = nums[j];            nums[j] = temp;        }        //交换锚点元素至临界位置        // swap(nums, start, j);用这个没有全部通过,bug        nums[start] = nums[j];        nums[j] = pivot;        return i;               //继承递归;        // quickSort(nums, start, i-1);        // quickSort(nums, i+1, end);    }    private void swap(int[] nums, int i, int j){        int temp = nums[i];        nums[i] = nums[j];        nums[j] = nums[i];    }}

但是这样写,面试官会让你优化的!

优化:增加pivot的随机性可以让算法更加稳定

Random.nextInt(n)方法,是生成一个随机的int值,该值介于[0,n)的区间

Random random = new Random();

// 在区间随机选择一个元素作为

if (start > end) {

int randomIndex = 1 + random.nextInt(end); //包含0 不包含end, 为了不是0, 加一个1;

swap(nums, start, randomIndex);

}

完整代码:

import java.util.Random;class Solution {    public int findKthLargest(int[] nums, int k) {        //                 int start = 0, end = nums.length - 1;        int kTarget = nums.length - k;        while(true){            int resIndex = quickSort(nums, start, end);            if(resIndex == kTarget){                return nums[resIndex];            }else if(resIndex > kTarget){                end = resIndex - 1;            }else if(resIndex < kTarget){                start = resIndex + 1;            }        }    }    //快排核心    private int quickSort(int[] nums, int start, int end){        //这里没有写递归终止条件,这题不是要递归排序        int i = start;        int j = end;                Random random = new Random();        // 在区间随机选择一个元素作为        if (start > end) {            int randomIndex = 1 + random.nextInt(end); //包含0 不包含end, 为了不是0, 加一个1;            swap(nums, start, randomIndex);        }        int pivot = nums[start]; //选择第一个为锚点元素        while(i < j){            while(i < j && nums[j] >= pivot){                j--;            }            while(i < j && nums[i] <= pivot){                i++;            }           //交换元素         //    swap(nums, i, j)   ; //用这个没有全部通过,bug            int temp = nums[i];            nums[i] = nums[j];            nums[j] = temp;        }        //交换锚点元素至临界位置        // swap(nums, start, j);用这个没有全部通过,bug        nums[start] = nums[j];        nums[j] = pivot;        return i;               //继承递归;        // quickSort(nums, start, i-1);        // quickSort(nums, i+1, end);    }    private void swap(int[] nums, int i, int j){        int temp = nums[i];        nums[i] = nums[j];        nums[j] = nums[i];    }}

加油啊:::::PPPP

标签: #n元数组所构成的空间的基