求第K大的数~~

本文介绍了一种使用快速排序思想求解序列中第k大数的方法,并提供了具体的实现代码,通过不断调整序列使分治点左侧的数不大于分治点,右侧的数不小于分治点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

已知n个数字各不相同,求其中第k大的数是多少?(1k≤n≤10000

这是一道简单的试题,我们完全可以套用常用的快速排序模型来解决,即对所有数字进行排序,然后取出第k大的数字输出即可,该算法的时间复杂度为Onlog2n

快速排序的基本思想关键在于不斷调整使分治点左边的数不大于(或不小于)分治点,右边的数不小于(或不大于)分治点。

一般快速排序,当找到一个分治点x,序列就以x为分治点,分成左右两部分。

假设每次找到的分治点接近中点,那么,其算法的时间代价大致为:n+n/2+n/4+n/8+…=2n.也就是说改进后的算法的时间复杂度为O(n).

namespace 求第k大的数

{

    class Program

    {

        static int maxn = 10001;//序列长度的上限

        static int[] arr = new int[maxn];//序列

        static void Main(string[] args)

        {

         

            int k, n;//序列长度为n,被寻找的数的大小为k

 

            Console.WriteLine("输入序列的长度");

                n = int.Parse(Console.ReadLine().Trim());

            Console.WriteLine("请输入序列:");

            for (int i = 1; i <= n; i++)

            {

                arr[i] = Convert.ToInt32(Console.ReadLine());

            }

            Console.WriteLine("您要寻找第几大的数?");

            k = int.Parse(Console.ReadLine());

            sort(1,n,k);

       

        }

 

        static void sort(int b_low, int b_high, int k)

        {

            int low = b_low, high = b_high;

            int mid = (low + high) / 2;

            int temp;

            while (low < high)

            {

                while (low < mid)

                {

                    if (arr[low] > arr[mid])

                    {

                        //swap(arr + low, arr + mid);

                        temp = arr[low];

                        arr[low] = arr[mid];

                        arr[mid] = temp;

                        mid = low;

                        low += 1;

                        break;

                    }

                    else

                    {

                        low++;

                    }

                }

                while (mid < high)

                {

                    if (arr[high] < arr[mid])

                    {

                        //swap(arr + high, arr + mid);

                        temp = arr[high];

                        arr[high] = arr[mid];

                        arr[mid] = temp;

                        mid = high;

                        high -= 1;

                        break;

                    }

                    else

                    {

                        high--;

                    }

                }

            }

            if (mid == k)

                Console.WriteLine(arr[mid]);

            else if (mid < k)

            {

                low = mid;

                high = b_high;

                sort(low, high, k);

            }

            else if (mid > k)

            {

                high = mid;

                low = b_low;

                sort(low, high, k);

            }

        }

    }

}

 

### 解决方案 为了在无序组中高效地找到第K,可以采用基于快速选择算法的方法。该方法源自快速排序的思想,在平均情况下具有线性时间复杂度O(n)[^1]。 #### 基本概念 快速选择是一种用于在线性时间内解决问题的选择算法。它通过分区操作来减少处理的据规模,直到定位到所需的元素位置为止。具体来说: - **分区函**:选定一个枢轴(pivot),通常可以选择第一个元素、最后一个元素或是随机选取; - **分割过程**:将所有小于等于枢轴的元素移动至其左侧,其余放置在其右侧; - **递归调用**:依据当前枢轴的位置决定下一步是在左半区还是右半区间继续执行相同的操作; 当目标索引正好对应于某个特定分界点时,则找到了所的第K值[^3]。 #### Python 实现代码 下面给出了一段Python版本的具体实现方式: ```python import random def find_kth_largest(nums, k): """返回列表 nums 中第 k 数字""" def partition(left, right, pivot_index): pivot_value = nums[pivot_index] # 将枢轴移到末尾 nums[pivot_index], nums[right] = nums[right], nums[pivot_index] store_index = left # 移动较小项到左边 for i in range(left, right): if nums[i] > pivot_value: # 寻找第k而非第k小因此这里使用> nums[store_index], nums[i] = nums[i], nums[store_index] store_index += 1 # 放回枢轴 nums[right], nums[store_index] = nums[store_index], nums[right] return store_index def select(left, right, k_smallest): """ 返回列表 nums 的子集 [left:right+1] 中第 k_smallest 小的数字, 即整个列表中的第 (len(nums)-k) 数字。 """ if left == right: return nums[left] # 随机化枢轴以提高性能稳定性 pivot_index = random.randint(left, right) pivot_index = partition(left, right, pivot_index) if k_smallest == pivot_index: return nums[k_smallest] elif k_smallest < pivot_index: return select(left, pivot_index - 1, k_smallest) else: return select(pivot_index + 1, right, k_smallest) n = len(nums) return select(0, n - 1, n - k) # 测试案例 print(find_kth_largest([3, 2, 1, 5, 6, 4], 2)) # 输出应为5 ``` 此代码实现了上述提到的核心逻辑,并且加入了随机化的策略来增强实际应用中的表现效果。需要注意的是,这里的`find_kth_largest()`函接收两个参——待查询的整型列表以及表示所需排名小的一个正整k。最终输出的结果即为目标值所在处的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值