活动介绍

用分治法从n个数中查找第k个小元素 。 输入 第一行,一个整数,表示元素的个数n;第二行,n个整数,表示n个元素;第三行,一个整数,表示k的值 。 输出 n个数中第k小元素 样例输入 Copy 6 5 2 9 12 8 10 3 样例输出 Copy 8

时间: 2024-02-15 07:02:44 浏览: 76
好的,这是一个经典的算法问题。使用分治法可以很快地找到第k小的元素。 具体实现方法如下: 1. 首先将n个数分成若干个大小相等的组,每组有m个数(m为一个常数,比如5)。 2. 对于每个组进行排序,选出每个组的中位数,将这些中位数组成一个新的数组,称为中位数数组。 3. 对于中位数数组,递归地寻找其中位数的中位数,记为x。 4. 将原始数组中小于x的数放在左边,大于x的数放在右边,等于x的数放在中间。 5. 记左边的数的个数为p,如果k<=p,则在左边寻找第k小的数;如果k>p,则在右边寻找第k-p小的数。 6. 递归地进行步骤4至5,直到找到第k小的数。 以下是实现这个算法的Python代码: ```python def find_kth_smallest(nums, k): if len(nums) == 1: return nums[0] else: # 将数组分为大小相等的5个组 groups = [nums[i:i+5] for i in range(0, len(nums), 5)] # 对每个组进行排序,选出中位数 medians = [sorted(group)[len(group)//2] for group in groups] # 递归地寻找中位数的中位数 x = find_kth_smallest(medians, len(medians)//2) # 将数组分为小于x、等于x和大于x的三部分 left = [num for num in nums if num < x] middle = [num for num in nums if num == x] right = [num for num in nums if num > x] # 计算左侧的数的个数 p = len(left) # 根据p和k的大小关系来确定在左侧还是右侧寻找第k小的数 if k <= p: return find_kth_smallest(left, k) elif k > p + len(middle): return find_kth_smallest(right, k-p-len(middle)) else: return x ``` 你可以将上述代码复制到你的Python环境中,并调用`find_kth_smallest`函数来测试。例如,你可以这样调用函数: ```python n = int(input()) nums = list(map(int, input().split())) k = int(input()) print(find_kth_smallest(nums, k)) ``` 输入示例: ``` 6 5 2 9 12 8 10 3 ``` 输出示例: ``` 8 ```
阅读全文

相关推荐

题目描述 给定一个含有n个数字的数组 a。 定义: 其中 & 运算表示为按位与。注意 l ≤ r l≤r。 对于以上描述,小可给出了q次查询。每次查询给出两个数字 l 和 k ,小可希望找出最大的 r ( l ≤ r ≤ n ) (l≤r≤n) ,使得 f ( l , r ) ≥ k f(l,r)≥k 输入描述 第一行:输入一个整数 t ,表示多组输入的样例组数。 对于每组测试数据: 第一行:输入一个正整数 n,表示数组长度。 第二行:输入 n 个正整数,表示数组a。 第三行:输入一个正整数 q,表示查询次数。 接下来q行:每行输入两个正整数 l 和 k ,表述如题 输出描述 对于每次查询,输出对应的答案,如果不存在这样的r,输出-1 。 输出格式为:同一组数据的答案在同一行,以空格为间隔;不同组数据以换行间隔。 输入样例 3 5 15 14 17 42 34 3 1 7 2 15 4 5 5 7 5 3 1 7 4 1 7 5 7 2 3 2 2 7 19 20 15 12 21 7 11 4 1 15 4 4 7 12 5 7 输出样例 2 -1 5 1 5 2 2 2 6 -1 5 数据描述 25%的数据下: t = 1 , 1 ≤ n ≤ 1 0 0 , q ≤ 1 0 0 0 t=1,1≤n≤100,q≤1000 100%的数据下: 1 ≤ t ≤ 1 0 4 , 1 ≤ n ≤ 2 × 1 0 5 , 1 ≤ a i ≤ 1 0 9 1≤t≤10 ​4 ​​ ,1≤n≤2×10 ​5 ​​ ,1≤a ​i ​​ ≤10 ​9 ​​ 1 ≤ q ≤ 1 0 5 , 1 ≤ l ≤ n , 1 ≤ k ≤ 1 0 9 1≤q≤10 ​5 ​​ ,1≤l≤n,1≤k≤10 ​9 ​​ 数据保证多组输入的 n 的和不超过 2 × 1 0 5 2×10 ​5 ​​ ,同时 q 的和不超过 2 × 1 0 5 2×10 ​5 ​​ 。 c++代码

静态链表示意图:2.2 顺序表与链表的比较存储密度比较:顺序表:只存储数据元素、预分配存储空间链表:指针的结构性开销、链表中的元素个数没有限制按位查找:顺序表:O(1),随机存取链表:O(n),顺序存取插入和删除:顺序表:O(n),平均移动表长一半的元素链表:不用移动元素,合适位置的指针——O(1)时间复杂度:顺序表:若线性表频繁查找却很少进行插入和删除操作链表:若线性表需频繁插入和删除时空间复杂度:顺序表:知道线性表的大致长度,空间效率会更高链表:若线性表中元素个数变化较大或者未知2.3 栈        定义:限定仅在一端(栈顶)进行插入和删除操作的线性表,后进先出。栈示意图:        时间复杂度(插入与删除):顺序栈与链栈均为O(1)        空间复杂度:链栈多一个指针域,结构性开销较大,使用过程中元素个数变化较大时,用链栈;反之顺序栈。        出栈元素不同排列的个数:   (卡特兰数)        共享栈: 两个栈共享一片内存空间, 两个栈从两边往中间增长。卡特兰数的应用:存储结构:顺序栈初始化:top=-1链栈初始化:top=NULL栈的应用:        1) 括号匹配        2) 递归        3) 中缀表达式 转 后缀表达式        4) 中缀表达式:设两个栈(数据栈和运算符栈),根据运算符栈的优先级进行运算。2.4 队列        定义: 只允许在一端插入, 在另一端删除。具有先进先出的特点。队列示意图:        时间复杂度:均为O(1)        空间复杂度:链队列多一个指针域,结构性开销较大;循环队列存在浪费空间和溢出问题。使用过程中元素个数变化较大时,用链队列;反之循环队列。        双端队列: 只允许从两端插入、两端删除的线性表。双端队列示意图: 存储结构:        链队列:队头指针指向队头元素的前一个位置,队尾指针指向队尾元素,先进先出。        循环队列:                1)队空:front=rear                2)队满:(rear+1)%QueueSize=front                3)队列元素个数:(队尾-队头+队长)%队长==(rear-front+QueueSize)%QueueSize队列的应用:        1) 树的层次遍历