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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

未能比较数组中的两个元素_算法3 寻找两个正序数组的中序数

發(fā)布時(shí)間:2023/12/19 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 未能比较数组中的两个元素_算法3 寻找两个正序数组的中序数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

問(wèn)題描述:

給定兩個(gè)大小為 m 和 n 的正序(從小到大)數(shù)組 nums1 和 nums2。請(qǐng)你找出并返回這兩個(gè)正序數(shù)組的中位數(shù)。要求設(shè)計(jì)一個(gè)時(shí)間復(fù)雜度為 O(log (m+n)) 的算法解決此問(wèn)題。

示例 1:

輸入:nums1 = [1,3], nums2 = [2]

輸出:2.00000

解釋:合并數(shù)組 = [1,2,3] ,中位數(shù) 2

示例 2:

輸入:nums1 = [1,2], nums2 = [3,4]

輸出:2.50000

解釋:合并數(shù)組 = [1,2,3,4] ,中位數(shù) (2 + 3) / 2 = 2.5

示例 3:

輸入:nums1 = [0,0], nums2 = [0,0]

輸出:0.00000

示例 4:

輸入:nums1 = [], nums2 = [1]

輸出:1.00000

示例 5:

輸入:nums1 = [2], nums2 = []

輸出:2.00000

提示:

nums1.length == m

nums2.length == n

0 <= m <= 1000

0 <= n <= 1000

1 <= m + n <= 2000

-106 <= nums1[i], nums2[i] <= 106

解題思路:

根據(jù)中位數(shù)的定義,當(dāng) m+n 是奇數(shù)時(shí),中位數(shù)是兩個(gè)有序數(shù)組中的第 (m+n)/2個(gè)元素,當(dāng) m+n 是偶數(shù)時(shí),中位數(shù)是兩個(gè)有序數(shù)組中的第 (m+n)/2個(gè)元素和第 (m+n)/2+1 個(gè)元素的平均值。因此,這道題可以轉(zhuǎn)化成尋找兩個(gè)有序數(shù)組中的第 k 小的數(shù),其中 k 為 (m+n)/2 或 (m+n)/2+1。假設(shè)兩個(gè)有序數(shù)組分別是A 和B。要找到第 k 個(gè)元素,我們可以比較A[k/2?1] 和 B[k/2?1],其中 /?表示整數(shù)除法。由于 A[k/2?1] 和 B[k/2?1] 的前面分別有 A[0..k/2?2] 和 B[0..k/2?2],即 k/2?1 個(gè)元素,對(duì)于 A[k/2?1] 和 B[k/2?1] 中的較小值,最多只會(huì)有(k/2?1)+(k/2?1)≤k?2 個(gè)元素比它小,那么它就不能是第 kk 小的數(shù)了。

因此我們可以歸納出三種情況:

  • 如果 A[k/2?1]

  • 如果 A[k/2?1]>B[k/2?1],則可以排除 B[0] 到 B[k/2?1]。

  • 如果 A[k/2?1]=B[k/2?1],則可以歸入第一種情況處理。

可以看到,比較 A[k/2?1] 和 B[k/2?1] 之后,可以排除 k/2 個(gè)不可能是第 k 小的數(shù),查找范圍縮小了一半。同時(shí),我們將在排除后的新數(shù)組上繼續(xù)進(jìn)行二分查找,并且根據(jù)我們排除數(shù)的個(gè)數(shù),減少 k 的值,這是因?yàn)槲覀兣懦臄?shù)都不大于第 k 小的數(shù)。

有以下三種情況需要特殊處理:

  • 如果 A[k/2?1] 或者 B[k/2?1] 越界,那么我們可以選取對(duì)應(yīng)數(shù)組中的最后一個(gè)元素。在這種情況下,我們必須根據(jù)排除數(shù)的個(gè)數(shù)減少 k 的值,而不能直接將 k 減去 k/2。

  • 如果一個(gè)數(shù)組為空,說(shuō)明該數(shù)組中的所有元素都被排除,我們可以直接返回另一個(gè)數(shù)組中第 k 小的元素。

  • 如果 k=1,我們只要返回兩個(gè)數(shù)組首元素的最小值即可。

用一個(gè)例子說(shuō)明上述算法。假設(shè)兩個(gè)有序數(shù)組如下:

A:1349B:123456789

兩個(gè)有序數(shù)組的長(zhǎng)度分別是 4 和 9,長(zhǎng)度之和是 13,中位數(shù)是兩個(gè)有序數(shù)組中的第 7 個(gè)元素,因此需要找到第 k=7 個(gè)元素。

比較兩個(gè)有序數(shù)組中下標(biāo)為 k/2?1=2 的數(shù),即 A[2] 和 B[2],如下面所示:

A: 1 3 4 9 ? ?↑

B: 1 2 3 4 5 6 7 8 9 ? ?↑

由于 A[2]>B[2],因此排除 B[0] 到 B[2],即數(shù)組B 的下標(biāo)偏移(offset)變?yōu)?3,同時(shí)更新 k 的值:k=k?k/2=4。

下一步尋找,比較兩個(gè)有序數(shù)組中下標(biāo)為 k/2?1=1 的數(shù),即 A[1] 和 B[4],如下面所示,其中方括號(hào)部分表示已經(jīng)被排除的數(shù)。

A: 1 3 4 9 ? ↑

B: [1 2 3] 4 5 6 7 8 9 ? ? ? ?↑

由于 A[1]

下一步尋找,比較兩個(gè)有序數(shù)組中下標(biāo)為 k/2?1=0 的數(shù),即比較 A[2] 和 B[3],如下面所示,其中方括號(hào)部分表示已經(jīng)被排除的數(shù)。

A: [1 3] 4 9 ? ? ?↑

B: [1 2 3] 4 5 6 7 8 9 ? ? ? ↑

由于 A[2]=B[3],根據(jù)之前的規(guī)則,排除 A 中的元素,因此排除 A[2],即數(shù)組 A 的下標(biāo)偏移變?yōu)?3,同時(shí)更新 k 的值:k=k?k/2=1。

由于 k 的值變成 1,因此比較兩個(gè)有序數(shù)組中的未排除下標(biāo)范圍內(nèi)的第一個(gè)數(shù),其中較小的數(shù)即為第 k 個(gè)數(shù),由于 A[3]>B[3],因此第 k 個(gè)數(shù)是 B[3]=4。

A: [1 3 4] 9 ? ? ? ↑

B: [1 2 3] 4 5 6 7 8 9 ? ? ? ↑

算法代碼:

class?Solution?{

????public?double?findMedianSortedArrays(int[]?nums1,?int[]?nums2)?{

????????int?length1?=?nums1.length,?length2?=?nums2.length;

????????int?totalLength?=?length1?+?length2;

????????if(totalLength?%?2?==?1){

????????????int?midIndex?=?totalLength?/?2;

????????????double?median?=?getKthElement(nums1,nums2,midIndex+1);

????????????return?median;

????????}else{

????????????int?midIndex1?=?totalLength?/?2?-?1,?midIndex2?=?totalLength?/?2;

????????????double?median?=?(getKthElement(nums1,?nums2,?midIndex1?+?1)?+?getKthElement(nums1,?nums2,?midIndex2?+1))?/?2.0;

????????????return?median;

????????}

????}

????public?int?getKthElement(int[]?nums1,?int[]?nums2,?int?k)?{

????????/*?主要思路:要找到第 k (k>1)?小的元素,那么就取 pivot1 = nums1[k/2-1]?和 pivot2 = nums2[k/2-1]?進(jìn)行比較

?????????*?這里的?"/"?表示整除

?????????*?nums1?中小于等于?pivot1?的元素有?nums1[0?..?k/2-2]?共計(jì)?k/2-1?個(gè)

?????????*?nums2?中小于等于?pivot2?的元素有?nums2[0?..?k/2-2]?共計(jì)?k/2-1?個(gè)

?????????*?取?pivot?=?min(pivot1,?pivot2),兩個(gè)數(shù)組中小于等于?pivot?的元素共計(jì)不會(huì)超過(guò)?(k/2-1)?+?(k/2-1)?<=?k-2?個(gè)

?????????*?這樣?pivot?本身最大也只能是第?k-1?小的元素

?????????*?如果 pivot = pivot1,那么 nums1[0 .. k/2-1]?都不可能是第 k 小的元素。把這些元素全部?"刪除",剩下的作為新的 nums1 數(shù)組

?????????*?如果 pivot = pivot2,那么 nums2[0 .. k/2-1]?都不可能是第 k 小的元素。把這些元素全部?"刪除",剩下的作為新的 nums2 數(shù)組

?????????*?由于我們?"刪除"?了一些元素(這些元素都比第?k?小的元素要小),因此需要修改?k?的值,減去刪除的數(shù)的個(gè)數(shù)

?????????*/

????????int?length1?=?nums1.length,?length2?=?nums2.length;

????????int?index1?=?0,?index2?=?0;

????????int?kthElement?=?0;

????????while?(true)?{

????????????//?邊界情況

????????????if?(index1?==?length1)?{

????????????????return?nums2[index2?+?k?-?1];

????????????}

????????????if?(index2?==?length2)?{

????????????????return?nums1[index1?+?k?-?1];

????????????}

????????????if?(k?==?1)?{

????????????????return?Math.min(nums1[index1],?nums2[index2]);

????????????}

????????????//?正常情況

????????????int?half?=?k?/?2;

????????????int?newIndex1?=?Math.min(index1?+?half,?length1)?-?1;

????????????int?newIndex2?=?Math.min(index2?+?half,?length2)?-?1;

????????????int?pivot1?=?nums1[newIndex1],?pivot2?=?nums2[newIndex2];

????????????if?(pivot1?<=?pivot2)?{

????????????????k?-=?(newIndex1?-?index1?+?1);

????????????????index1?=?newIndex1?+?1;

????????????}?else?{

????????????????k?-=?(newIndex2?-?index2?+?1);

????????????????index2?=?newIndex2?+?1;

????????????}

????????}

????}

}

總結(jié)

以上是生活随笔為你收集整理的未能比较数组中的两个元素_算法3 寻找两个正序数组的中序数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。