递归训练2:求两个有序数组的第K小数

 解题思路:

开始思路想的是两个数组有序,通过两个数组相互对比,那么把寻找第k小的数转换成选择最小数,找到之后跳过,然后循环k次,这样必须循环k次,而且每次还要对比,时间复杂度太高。

优化之后,解题思路与下面这个很类似。

递归训练1:在两个长度相等的排序数组中找到上中位数

每次寻找时,将两个数组mid1=k/2;mid2=k/2;

此时 arr2[mid2] > arr1[mid1],那么问题转化为在数组 arr1[mid1+1...m1]和数组 arr2[0...m2] 寻找第
K-md1-1)小的元素。 (这类似于二分查找,效率比较高)

这里k从0开始算起,也就是第0小元素开始,令k=k-1;

不过这里需要注意的是,有可能 k/2 的值是⼤于 m1 或者 m2的,所以如果 k/2 > m1 或者 m2 的话,我
们直接令 md1 = m1-1 或者 md2 = m2-1 就行了。

 1 class Solution {
 2 public:
 3     int get_k_min(int arr1[], int arr2[], int k) 
 4     {
 5         int data;
 6         if (arr1==NULL || arr1.length < 1)
 7         {
 8             return arr2[k-1];
 9         }
10         if (arr2==NULL || arr2.length < 1)
11         {
12             return arr1[k-1];
13         }
14         data = k_min(arr1, 0, arr1.length-1, arr2, 0 arr2.length-1, k-1);
15         return data;
16     }
17 
18 int  k_min(int arr1[], int L1, int R1, int arr2, int L2, int R2, int k)
19 {
20     //递归结束条件,是否超出数组大小
21     if (L1 > R1)
22     {
23         return arr2[L1+k];
24     }
25     if (L2 > R2)
26     {
27         return arr1[L1+k];
28     }
29     //递归结束,寻找到第k个小的数
30     if (k==0)
31     {
32         if (arr1[L1] <arr2[L2])
33         {
34             return arr1[L1];
35         }
36         if (arr1[L1] >arr2[L2])
37         {
38             return arr2[L2];    
39         }
40         return arr1[L1];    //return arr2[L2];
41     }
42 
43     int mid1 = L1 + k/2 < R1 ? L1 + k/2:R1;
44     int mid2 = L2 + k/2 < (R2-L1) ? L2 + k/2:R2;
45     if (arr1[mid1] < arr2[mid2])
46     {
47         k_min(arr1, mid1+1, R1, arr2, L2, R2, k-k/2-1);
48     }
49     else if (arr1[mid1] > arr2[mid1])
50     {
51         k_min(arr1, L1, R1, arr2, mid2, R2, k-k/2-1);
52     }
53     else
54         return arr1[mid1];    //return arr2[mid2];
55 }
56 
57 };
原文地址:https://www.cnblogs.com/Tavi/p/12530380.html