分治法,快速排序,快速选择排序

找第k个大的数

快速排序排好然后找第k个:

class Solution {
    public int findKthLargest(int[] nums, int k) {
            // 获得第K大的数
    
        // 这里稍微注意一下k-1,由于数组下标从0开始,第k大的数下标应该是k-1,所以修改了一下
        return quick_sort(nums, nums.length-k, 0, nums.length - 1);
    }

  
     private int quick_sort(int s[],int k, int l, int r)
    {
    if (l < r)
    {
        //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
        int i = l, j = r, x = s[l];
        while (i < j)
        {
            while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
                j--;  
            if(i < j) 
                s[i++] = s[j];
            
            while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
                i++;  
            if(i < j) 
                s[j--] = s[i];
        }
        s[i] = x;
        quick_sort(s, k,l, i - 1); // 递归调用 
        quick_sort(s, k,i + 1, r);
        
     }
         return s[k];
}
}

quickSelect sort:

class Solution {
    public int findKthLargest(int[] nums, int k) {
            // 获得第K大的数
    
        // 这里稍微注意一下k-1,由于数组下标从0开始,第k大的数下标应该是k-1,所以修改了一下
        return helper(nums, nums.length-k, 0, nums.length - 1);
    }

    private int helper(int[] nums, int k, int left, int right){
        if(left == right){
            // 只有1个数,那么就是这个数了
            return nums[left];
        }

        int i = left;   // 左边标志位
        int j = right;  // 右边标志位
        int key = nums[i]; // key值

        while(i < j){ 
            // j向前搜索,找到第一个小于key的值
            while(nums[j] >= key && i < j){
                j--;
            }
            // 交换nums[i]和nums[j]
            if(nums[j] < key && i < j){
                nums[i] = nums[j];
                i++; // 填坑后移
            }

            // i向后搜索,找到第一个大于key的值
            while(nums[i] <= key && i < j){
                i++;
            }
            // 交换nums[i]和nums[j]
            if(nums[i] > key && i < j){
                nums[j] = nums[i];
                j--;
            }
        }
        // 现在i 和 j相同,把key填进来
        nums[i] = key;
        // 递归左边部分和右边部分
        if(left < i && k < i){
            return helper(nums, k, left, i - 1);
        }
        if(right > j && k > j){
            return helper(nums, k, j + 1, right);
        }
        return nums[i]; // i == k
    }

    
}

用sort()排序

class Solution {
    public int findKthLargest(int[] nums, int k) {
        final int N = nums.length;
        Arrays.sort(nums);
        return nums[N - k];
}

    
}

用纯纯的QuickSort排序:

class Solution {
    public int findKthLargest(int[] nums, int k) {
            // 获得第K大的数
    
        // 这里稍微注意一下k-1,由于数组下标从0开始,第k大的数下标应该是k-1,所以修改了一下
        quick_sort(nums, 0, nums.length - 1);
        return nums[nums.length-k];
    }

  
     private void quick_sort(int s[],int l, int r)
    {
    if (l < r)
    {
        //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
        int i = l, j = r, x = s[l];
        while (i < j)
        {
            while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
                j--;  
            if(i < j) 
                s[i++] = s[j];
            
            while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
                i++;  
            if(i < j) 
                s[j--] = s[i];
        }
        s[i] = x;
        quick_sort(s,l, i - 1); // 递归调用 
        quick_sort(s,i + 1, r);
        
     }
        
}
}

猜你喜欢

转载自www.cnblogs.com/haojiesky/p/10791967.html