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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

LeetCode 4. 寻找两个有序数组的中位数(二分查找,难)

發布時間:2024/7/5 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 4. 寻找两个有序数组的中位数(二分查找,难) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1. 題目
    • 2. 解題
      • 2.1 合并數組
      • 2.2 優化2.1解法,雙指針
      • 2.3 二分法(找第k個數)
      • 2.4 切分法

1. 題目

給定兩個大小為 m 和 n 的有序數組 nums1 和 nums2。

請你找出這兩個有序數組的中位數,并且要求算法的時間復雜度為O(log(m+n))O(log(m + n))O(log(m+n))

你可以假設 nums1 和 nums2 不會同時為空。

示例 1: nums1 = [1, 3] nums2 = [2] 則中位數是 2.0示例 2: nums1 = [1, 2] nums2 = [3, 4] 則中位數是 (2 + 3)/2 = 2.5

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。

2. 解題

2.1 合并數組

  • 合并兩個數組,再取中位數
  • 時間和空間復雜度均為 O(m+n)
class Solution { public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n1 = nums1.size(), n2 = nums2.size(), len;len = n1 + n2;vector<int> nv(len);int i = 0, j = 0, k = 0;while(i < n1 && j < n2){if(nums1[i] < nums2[j])nv[k++] = nums1[i++];elsenv[k++] = nums2[j++];}if(i == n1){while(j < n2)nv[k++] = nums2[j++];}else{while(i < n1)nv[k++] = nums1[i++];}if(len%2)return nv[len/2];return (nv[len/2]+nv[len/2-1])/2.0;} };

2.2 優化2.1解法,雙指針

  • 不合并兩個數組,設置雙指針在兩個數組上
  • 比較大小,分別移動各自的指針,遍歷到中間的計數停止
  • 時間復雜度 O(m+n),空間復雜度 O(1)
class Solution { public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n1 = nums1.size(), n2 = nums2.size(), len;len = n1 + n2;vector<int> nv(len);int i = 0, j = 0, k, left = -1, right = -1;for(k = 0; k <= len/2; ++k){left = right;if(i < n1 && (j >= n2 || nums1[i] < nums2[j]))right = nums1[i++];elseright = nums2[j++];}if(len%2)return right;return (left+right)/2.0; } };

2.3 二分法(找第k個數)

參考鏈接,解法3



class Solution { public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n1 = nums1.size(), n2 = nums2.size(), len, kth;len = n1 + n2;kth = (len+1)/2;if(len%2)return findKth(nums1,0,n1-1,nums2,0,n2-1,kth);return (findKth(nums1,0,n1-1,nums2,0,n2-1,kth)+findKth(nums1,0,n1-1,nums2,0,n2-1,kth+1))/2.0; }int findKth(vector<int>& nums1, int s1, int e1, vector<int>& nums2, int s2, int e2, int kth){int len1 = e1-s1+1;int len2 = e2-s2+1;if(len1 > len2) //確保傳進來的參數len1是較短的數組(它先空)return findKth(nums2,s2,e2,nums1,s1,e1,kth);if(len1 == 0)return nums2[s2+kth-1];//一個為空,直接找到答案if(kth == 1)return min(nums1[s1],nums2[s2]);int i = s1+min(len1,kth/2)-1;//min使得指針不會越界int j = s2+min(len2,kth/2)-1;if(nums1[i] > nums2[j])//舍去nums2前面的return findKth(nums1,s1,e1,nums2,j+1,e2,kth-(j-s2+1));else//舍去nums1前面的return findKth(nums1,i+1,e1,nums2,s2,e2,kth-(i-s1+1));} };

O(lg(m+n))O(lg(m+n))O(lg(m+n))時間復雜度,尾遞歸,無需堆棧,空間復雜度 O(1)O(1)O(1)

2.4 切分法

  • 放了方便處理,確保A數組長度較短
  • 初始狀態下mid1取數組1的中間,mid1,mid2左半邊的總個數 == 右半邊 或者 比右半邊少1
  • 對mid1進行二分查找,相應的mid2會隨動(mid2=allHalf?mid1mid2 = allHalf - mid1mid2=allHalf?mid1
  • 如果 lmax1<=rmin2,andlmax2<=rmin1lmax1 <= rmin2 ,\quad and \quad lmax2 <= rmin1lmax1<=rmin2,andlmax2<=rmin1 , 成功找到分界線
  • Lmax=max(lmax1,lmax2))Lmax = max(lmax1,lmax2))Lmax=max(lmax1,lmax2)), Rmin=min(rmin1,rmin2)Rmin = min(rmin1, rmin2)Rmin=min(rmin1,rmin2),總個數為奇數返回RminRminRmin, 偶數返回(Lmax+Rmin)/2.0(Lmax+Rmin)/2.0(Lmax+Rmin)/2.0
class Solution { public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int n1 = nums1.size(), n2 = nums2.size();if(n1 > n2)//確保n1是較短的數組return findMedianSortedArrays(nums2, nums1);int left = 0, right = n1, allHalf = (n1+n2)/2, mid1, mid2;int lmax1, rmin1, lmax2, rmin2;while(left <= right){mid1 = left+((right-left)>>1);mid2 = allHalf - mid1;lmax1 = (mid1-1 >= 0) ? nums1[mid1-1] : INT_MIN;rmin1 = (mid1 < n1) ? nums1[mid1] : INT_MAX;lmax2 = (mid2-1 >= 0) ? nums2[mid2-1] : INT_MIN;rmin2 = (mid2 < n2) ? nums2[mid2] : INT_MAX;//在邊界處,認為沒有元素,設置成最大或者最小,保證下面關系式成立if(lmax1 > rmin2)right = mid1-1;else if(lmax2 > rmin1)left = mid1+1;else{left = right = mid1;break;}}int i = left, j = allHalf-left;int l = max(i-1 >= 0 ? nums1[i-1] : INT_MIN,j-1 >= 0 ? nums2[j-1] : INT_MIN);int r = min(i < n1 ? nums1[i] : INT_MAX,j < n2 ? nums2[j] : INT_MAX);if((n1+n2)%2 == 1)return r;return (l+r)/2.0;} };

總結

以上是生活随笔為你收集整理的LeetCode 4. 寻找两个有序数组的中位数(二分查找,难)的全部內容,希望文章能夠幫你解決所遇到的問題。

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