代码搬运工之面试常撕题篇一

代码搬运工之面试常撕题篇一

熟读力扣300题,不会写题也会敲。

排序

面试官:写个快排吧
你:我擦,幸亏准备了,快排我写的很快。
为什么让你写快排?
因为面试官想看你写得到底有多快,不快的男人不是一个好程序员。

public static void quickSort(int[] nums, int low, int high) {

        if (low < high) {
            int index = partition(nums, low, high);
            quickSort(nums, low, index - 1);
            quickSort(nums, index + 1, high);
        }

    }
    public static int partition(int[] nums, int left, int right) {
        //基准值
        int pivot = nums[left];
        while (left < right) {
            //从右往左扫描
            while (left < right && nums[right] >= pivot) {
                right--;
            }
            //找到第一个比pivot小的元素
            if (left < right) nums[left] = nums[right];
            //从左往右扫描
            while (left < right && nums[left] <= pivot) {
                left++;
            }
            //找到第一个比pivot大的元素
            if (left < right) nums[right] = nums[left];
        }
        //基准数放到合适的位置
        nums[left] = pivot;
        return left;
    }

快排写法很多,这里写的就是以一个元素为基准,找到它应该在位置(排好序后的位置),这个位置上的元素是对的,它右边的元素都比他大,左边的元素都比他小,然后对它左边和右边的也按照这个规则。最终每个元素都找到了自己的位置。
partition这个函数,就是为了给left这个位置的元素找到排序后的位置。
举个用快排思想的题目
BM47 寻找第K大
有一个整数数组,请你根据快速排序的思路,找出数组中第 k 大的数。
给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在。
要求:时间复杂度 O(nlogn)O(nlogn),空间复杂度 O(1)O(1)

 public static int findKth(int[] a, int n, int K) {
        // write code here
        int res = quicksort(a,0,a.length-1,K);
        return res;

    }
    public  static int  quicksort(int []a ,int left , int right,int k){
        if(left<right){
            int id = partion(a,left,right);
            if(id==a.length-k)//如果这个位置正好是第k大的数的位置,直接返回。
                return a[id];
            if(id<a.length-k)//如果这个位置正好小于第k大的数的位置,只需要对它右边进行快排,因为右边的都比它大。
                return quicksort(a,id+1,right,k);
            if(id>a.length-k)//同上
                return quicksort(a,left,id-1,k);
        }
        return a[left];
    }

    private static int partion(int[] a, int left, int right) {
        Random random = new Random();
        int rand = random.nextInt(right-left+1)+left;//随机一个基准,可以避免在有序的情况下,快排会失效
       int pivot = a[rand];
       int temp = a[left];
       a[left]=pivot;
       a[rand]=temp;
       while (left<right){
           while (left<right && a[right]>=pivot)
               right--;
           if(left<right)
               a[left]=a[right];
           while (left<right && a[left]<=pivot)
               left++;
           if(left<right)
               a[right]=a[left];
       }
        a[left]=pivot;
       return left;
    }

主要会存在快排失效的问题,会导致个别测试用例不通过,所以要改进一下,基准不是以第一个为准,而是随机生成一个基准,然后和第一个位置交换,其他的和之前的一样。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值