Coursera Algorithms week3 快速排序 练习测验: Selection in two sorted arrays(从两个有序数组中寻找第K大元素)

题目原文

Selection in two sorted arrays. Given two sorted arrays a[] and b[], of sizes n1 and n2, respectively, design an algorithm to find the kth largest key. The order  of growth of the worst case running time of your algorithm should be logn, where n = n1 + n2.

Version 1 : n1 = n2 and k = n/2

Version 2: k = n/2

Version 3: no restrictions

分析:

这个题目是要求从两个有序数组中寻找第K大元素,直观解法就是把连个数组归并排序,这样时间复杂度就是O(n),但是题目只要求知道第K大元素,其余比K大的元素的排列顺序并不关心。

默认数组a和数组b都是从小到大排序的。不论第K大元素在a或b中,其右侧元素一定大于K,可考虑分别从a和b中排除右侧(k-1)/2个元素,剩下的就是在未排除区间寻找第(k-已排除元素)大元素。通过递归逐步缩小比较范围。具体算法见如下代码。

 1 package week3;
 2
 3 import java.util.Arrays;
 4 import edu.princeton.cs.algs4.StdRandom;
 5
 6 public class KthInTwoSortedArrays {
 7     /**
 8      * 寻找第K大元素
 9      * @param a 数组a
10      * @param alo a的查找区间下界
11      * @param ahi a的查找区间上界
12      * @param b 数组b
13      * @param blo b的查找区间下界
14      * @param bhi b的查找区间上界
15      * @param k 当前查找区间的第k大元素
16      * @return
17      */
18     private static int find(int[] a, int alo, int ahi,int[] b, int blo, int bhi, int k){
19         if(alo > ahi) return b[bhi-k+1];
20         if(blo > bhi) return a[ahi-k+1];
21         if(k==1) return a[ahi] > b[bhi]? a[ahi]:b[bhi];
22         //直接用bhi-(k-1)/2或ahi-(k-1)/2进行查找可能会将第K个元素给漏掉
23         int bt = bhi-(k-1)/2 > blo ? bhi-(k-1)/2:blo;
24         int at = ahi-(k-1)/2 > alo ? ahi-(k-1)/2:alo;
25         if(a[at] >= b[bt])
26             return find(a,alo,at-1,b,blo,bhi,k-(ahi-at+1));
27         else
28             return find(a,alo,ahi,b,blo,bt-1,k-(bhi-bt+1));
29     }
30
31     public static void main(String[] args){
32         int n = 10;
33         int n1 = StdRandom.uniform(n);
34         int n2 = n-n1;
35         int[] a = new int[n1];
36         int[] b = new int[n2];
37         for(int i=0;i<n1;i++){
38             a[i] = StdRandom.uniform(100);
39         }
40         for(int i=0;i<n2;i++){
41             b[i] = StdRandom.uniform(100);
42         }
43         Arrays.sort(a);
44         Arrays.sort(b);
45         System.out.println("a="+Arrays.toString(a));
46         System.out.println("b="+Arrays.toString(b));
47         int[] c = new int[n];
48         int i = 0;
49         int j = 0;
50         int l = 0;
51         while(l<n){
52             if(i>=n1) c[l++] = b[j++];
53             else if(j>=n2) c[l++] = a[i++];
54             else{
55                 if(a[i] <= b[j])
56                     c[l++] = a[i++];
57                 else
58                     c[l++] = b[j++];
59             }
60
61         }
62         System.out.println("c="+Arrays.toString(c));
63
64         int k =StdRandom.uniform(1,n);
65         int largestK = find(a,0,n1-1,b,0,n2-1,k);
66         System.out.println("第"+k+"大元素是:"+largestK);
67     }
68 }
时间: 2024-12-22 03:23:33

Coursera Algorithms week3 快速排序 练习测验: Selection in two sorted arrays(从两个有序数组中寻找第K大元素)的相关文章

Coursera Algorithms week3 快速排序 练习测验: Nuts and bolts

题目原文: Nuts and bolts. A disorganized carpenter has a mixed pile of n nuts and n bolts. The goal is to find the corresponding pairs of nuts and bolts. Each nut fits exactly one bolt and each bolt fits exactly one nut. By fitting a nut and a bolt toget

用快速排序法寻找第k大元素

#include<iostream> #include<algorithm> #include<iterator> #include<cstdio> using namespace std; // 求首元素.中间元素和尾元素的中位数,将中位数与首元素交换位置 inline void medianAsPivot(int arr[], const int& left, const int& right) { const int middle =

巧妙利用快速排序法的原理求一个数组中的第10大元素

//快速排序法 int QuickSort_process3(int *a, int low, int high) { int l, h, temp; l = low; h = high; temp = a[low]; while (l < h){ while (l< h&&a[h] >= temp) --h; if (l < h) a[l] = a[h]; while (l < h&&a[l] < temp) ++l; if (l &l

Coursera Algorithms week3 归并排序 练习测验1: Merging with smaller auxiliary array

题目原文: Suppose that the subarray a[0] to a[n-1] is sorted and the subarray a[n] to a[2*n-1] is sorted. How can you merge the two subarrays so that a[0] to a[2*n-1] is sorted using an auxiliary array of length n (instead of 2n) 分析: 对两个大小分别为n的有序子数组进行归并,

【算法导论学习-015】数组中选择第i小元素(Selection in expected linear time)

1.算法思想 问题描述:从数组array中找出第i小的元素(要求array中没有重复元素的情况),这是个经典的"线性时间选择(Selection in expected linear time)"问题. 思路:算法导论215页9.2 Selection in expect linear time 2.java实现 思路:算法导论216页伪代码 /*期望为线性时间的选择算法,输入要求,array中没有重复的元素*/ public static int randomizedSelect(i

leetcode 215. 数组中的第K个最大元素(快速排序)

在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2输出: 5示例 2: 输入: [3,2,3,1,2,4,5,5,6] 和 k = 4输出: 4说明: 你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度. 来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/kth-largest-element-in-

求出数组前面k个元素或数组中元素大于一半的元素(快速排序与堆排序的灵活运用)

写这个的目的在于,说明快速排序的灵活运用.我们来看下关于快速排序中的一部分关键代码: 快速排序代码: int a[101],n;//定义全局变量,这两个变量需要在子函数中使用 void quicksort(int left,int right) { int i,j,t,temp; if(left>right) return; temp=a[left]; //temp中存的就是基准数 i=left; j=right; while(i!=j) { //顺序很重要,要先从右边开始找 while(a[j

leetcode -- Algorithms -- 4_ Median of Two Sorted Arrays

00 There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). class Solution(object): def findMedianSortedArrays(self, nums1, nums2): new

寻找数组中第k个最小值,使用快速排序

快速排序的一个特点是:每一次分区(partition)操作之后,就有一个元素被放在了数组的最终位置,在以后的排序过程中该元素位置不会变动: 利用这个特点我们可以将快速排序稍加改造来寻找第k个最小值,假设在一次分区操作之后中枢(pivot)的位置在k之前,那么我们下次只需要在中枢的后面进行查找:如果中枢的位置在k之后,那么我们下次只需要在中枢之前进行查找,直到中枢等于k为止. 我们知道快速排序的时间复杂度为O(nlgn),因为在寻找第k个最小的值时,我们只需要在中枢的一侧进行查找,所以通常来说这个