算法小练习之查找第K大的元素

173 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

1、前言

每天一个算法小练习,本篇使用Java实现。

2、题目描述

给定一个无序的整型数组A[n],数组大小大于等于3,允许有值相同的元素;请设计算法找到该数组排序后第K大的元素值并输出。

2.1、示例1

输入:

2,3,6,3,5,1,7,8
5

输出:

6

3、解题思路

排序

将无序数组从小到大进行排序,然后在排好序的数组中根据下标,就可以找到第K大的元素值了。但问题是,排序算法有很多种,采用何种排序算法就考察到我们对于常用排序算法的掌握情况。

常用排序算法:

排序算法时间复杂度空间复杂度稳定性
冒泡排序O(n2)O(n^2)O(1)O(1)稳定
选择排序O(n2)O(n^2)O(1)O(1)不稳定
插入排序O(n2)O(n^2)O(1)O(1)稳定
希尔排序O(n1.3)O(n^1.3)O(1)O(1)不稳定
快速排序平均O(nlogn)O(nlogn),最坏O(n2)O(n^2)O(1)O(1)不稳定
归并排序O(nlogn)O(nlogn)O(n)O(n)稳定
堆排序O(nlogn)O(nlogn)O(1)O(1)不稳定

可以看到,冒泡、选择、插入排序,它们的时间复杂度都是指数级.随意我们要选择快排、归并、堆排序中的一种。

本次使用快速排序实现。快速排序采用了分治的思想,根据基准数,将数组划分,比如将比基准数大的划分到左边,比基准数小的划分到右边。然后再递归进行划分操作,直到每个子区间都只有一个元素,排序完成。

实现代码

public static void main(String args[]) {
        int[] array = new int[]{2, 3, 3, 6, 5, 1, 7, 8};
        //先对无序数组进行排序,得到有序数组
        quickSort(array, 0, array.length - 1);
        int k = 5;
        System.out.println("第" + k + "大元素是:" + array[k]);
    }

    /**
     *  快排
     */
    public static void quickSort(int[] array, int startIndex, int endIndex) {
        //递归结束条件:startIndex大等于endIndex的时候
        if (startIndex >= endIndex) {
            return;
        }
        //得到基准元素位置
        int pivotIndex = partition(array, startIndex, endIndex);
        //用分治法递归数例的两部分
        quickSort(array, startIndex, pivotIndex - 1);
        quickSort(array, pivotIndex + 1, endIndex);
    }

    /**
     * 快速排序得到基准元素
     */
    private static int partition(int[] array, int startIndex, int endIndex) {
        //取第一个位置的元素作为基准元素
        int pivot = array[startIndex];
        int left = startIndex;
        int right = endIndex;
        //找到初始值等于pivot的位置
        int index = startIndex;
        //大循环在左右指针重合或者交错的时候结束
        while (right >= left) {
            //right指针从右向左进行比较
            while (right >= left) {
                if (array[right] < pivot) {
                    array[left] = array[right];
                    index = right;
                    left++;
                    break;
                }
                right--;
            }
            //left指针从左向右进行比较
            while (right >= left) {
                if (array[left] > pivot) {
                    array[right] = array[left];
                    index = left;
                    right--;
                    break;
                }
                left++;
            }
        }
        array[index] = pivot;
        return index;
    }

5、执行结果

1655390396547.png

好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊