日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言求一个数组中第k大的数,leetcode | Median of Two Sorted Arrays 寻找2个有序数组中第k大的值...

發布時間:2024/7/19 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言求一个数组中第k大的数,leetcode | Median of Two Sorted Arrays 寻找2个有序数组中第k大的值... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

There are two sorted arrays A and B 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)).

分析

本題更經典通用的描述方式時:

給定2個有序數組,找出2個數組中所有元素中第k大的元素。

思路1

直觀思路就是類似merge-sort,將2個數組merge成一個數組,即可得到第k大的值,但是時間復雜度O(m+n);

思路2

然后我們僅需要第k大的元素,不需要排序這個復雜的操作:可以定義一個計數器m,表示找到了第m大的元素;同時指針pa,pb分別指向數組A,B的第一個元素,使用merge-sort的方式,當A的當前元素小于B的當前元素時:pa++, m++,當*pb < *pa時,pb++, m++。最終當m等于k時,就得到了第k大的元素。時間復雜度O(k),但是當k接近于m+n時,復雜度還是O(m+n);

思路3

從題目中的要求O(log(m+n))可以聯想到肯定要用到二分查找的思想

那么有沒有更好的方案?我們可以考慮從k入手。如果我們每次能夠刪除一個一定處于第k大元素之前的元素,那么需要進行k次。但是如果我們每次都能刪除一半呢?可以利用A,B有序的信息,類似二分查找,也是充分利用有序。

假設A 和B 的元素個數都大于k/2,我們將A 的第k/2 個元素(即A[k/2-1])和B 的第k/2個元素(即B[k/2-1])進行比較,有以下三種情況(為了簡化這里先假設k 為偶數,所得到的結論對于k 是奇數也是成立的):

- A[k/2 - 1] == B[k/2 - 1];

- A[k/2 - 1] > B[k/2 - 1];

- A[k/2 - 1] < B[k/2 - 1];

如果A[k/2 - 1] < B[k/2 - 1] ,意味著 A[0] 到 A[k/2 - 1] 的元素一定小于 A+B 第k大的元素。因此可以放心的刪除A數組中的這k/2個元素;

同理,A[k/2 - 1] > B[k/2 - 1];可以刪除B數組中的k/2個元素;

當A[k/2 - 1] == B[k/2 - 1] 時,說明找到了第k大的元素,直接返回A[k/2 - 1] 或B[k/2 - 1]的值。

因此可以寫一個遞歸實現,遞歸終止條件是什么呢?

- A或B為空時,直接返回A[k-1] 或 B[k-1]

- 當k = 1時,返回min(A[0], B[0]) //第1小表示第一個元素

- 當A[k/2 - 1] == B[k/2 - 1] 時,返回A[k/2 - 1] 或B[k/2 - 1]

C語言實現

static int find_kth(int* A, int m,int* B, int n, int k);

static int min(p, q) {return (p < q) ? p : q;}

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {

int m = nums1Size;

int n = nums2Size;

int total = m+n;

int k = total/2;

if(total & 0x01) {

return find_kth(nums1, m, nums2, n, k+1); //奇數,返回唯一中間值

} else {

return (find_kth(nums1, m, nums2, n, k) + find_kth(nums1, m, nums2, n, k+1)) / 2.0; //偶數,返回中間2個的平均值

}

}

//找到A,B組合中第k小的值: AB[k-1]

int find_kth(int* A, int m,int* B, int n, int k) {

//假設m都小于n

if (m > n)

return find_kth(B, n, A, m, k);

if (m == 0)

return B[k-1];

if (k == 1) //終止條件

return min(A[0], B[0]);

int i_a = min(m, k/2);

int i_b = k - i_a;

if (A[i_a-1] < B[i_b-1])

return find_kth(A+i_a, m-i_a, B, n, k-i_a);

else if (A[i_a-1] > B[i_b-1])

return find_kth(A, m, B+i_b, n-i_b, k-i_b);

else

return A[i_a-1];

}

總結

以上是生活随笔為你收集整理的C语言求一个数组中第k大的数,leetcode | Median of Two Sorted Arrays 寻找2个有序数组中第k大的值...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。