使用二分法搜尋合適的i值,計算對應的j值,最後經過分類討論nums1和nums2的多種狀況計算獲得中值。數組
二分法的關鍵思想是 假設該數組的長度是N那麼二分後是N/2,再二分後是N/4……直到二分到1結束(固然這是屬於最壞的狀況了,即每次找到的那個中點數都不是咱們要找的),那麼二分的次數就是基本語句執行的次數,因而咱們能夠設次數爲x,N*(1/2)^x=1;則x=logn,底數是2。學習
所以,該問題的時間複雜度是 O(log(min(m,n)).spa
空間複雜度 O(m+n)code
class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { double ans; int len1 = nums1.size(); int len2 = nums2.size(); if (len1 > len2){ vector<int> temp(nums1); nums1 = nums2; nums2 = temp; len1 = nums1.size(); len2 = nums2.size(); } // if nums1 is empty if (len1 == 0){ if (len2 % 2 == 0) return ans = 0.5*(nums2[len2/2 - 1] + nums2[len2/2]); else return ans = nums2[int(len2/2)]; } int i = 0, j = 0; int imin = 0, imax = len1; // 這兩個變量用於二分法 while(imin <= imax){ // 二分法的開展條件 i = int(0.5*(imin+imax)); j = getValueJ(len1,len2,i); if(i==0 || j==len2 || nums1[i-1] <= nums2[j]){ if(i==len1 || j==0 || nums1[i] >= nums2[j-1]){ ans = getMedian(nums1, nums2, len1, len2, i, j); break; } else{ imin = i+1; cout << "imin : " << imin << endl; } } else{ imax = i; } } return ans; } int getValueJ(int len1, int len2, int iIndex){ int jIndex; if ((len1+len2) % 2 == 0) jIndex = 0.5*(len1+len2) - iIndex; else jIndex = 0.5*(len1+len2+1) - iIndex; return jIndex; } double getMedian(vector<int> &num1, vector<int> &num2, int len1, int len2, int iIndex, int jIndex){ /********* for (int i = 0; i < len1; i++) cout << num1[i] << " "; cout << endl; for (int j = 0; j < len2; j++) cout << num2[j] << " "; cout << endl; cout << "iIndex : "<< iIndex << endl; cout << "jIndex : "<< jIndex << endl; cout << "len1 : " << len1 << endl; cout << "len2 : " << len2 << endl; **********/ double median; vector<int> leftP, rightP; if ((len1+len2) % 2 ){ cout << "the sum of two vector is odd number" << endl; // we know that size of vector leftP is bigger than that of vector rightP if (iIndex > 0 && jIndex > 0){ vector<int> tmp; for (int i = 0; i < iIndex; i++) tmp.push_back(num1[i]); for (int j = 0; j < jIndex; j++) tmp.push_back(num2[j]); median = *max_element(tmp.begin(), tmp.end()); } else if (iIndex == 0) median = *max_element(num2.begin(), (num2.end()-(len2-jIndex))); else if (jIndex == 0) median = *max_element(num1.begin(), (num1.end()-(len1-iIndex))); } else{ cout << "the sum of two vector is even number" << endl; if (iIndex == 0){ leftP.clear(); rightP.clear(); for (int j = 0; j < jIndex; j++){ leftP.push_back(num2[j]); } rightP = num1; if(jIndex < len2) for(int j = jIndex; j < len2; j++) rightP.push_back(num2[j]); /************** cout << "leftP : "; for(int i = 0; i < leftP.size(); i++) cout << leftP[i] << " "; cout << endl << "rightP : "; for(int j = 0; j < rightP.size(); j++) cout << rightP[j] << ""; cout << endl; **************/ } else if (iIndex == len1){ leftP.clear(); rightP.clear(); leftP = num1; if (jIndex > 0 && jIndex < len2) for (int j = 0; j < jIndex; j++) leftP.push_back(num2[j]); for (int j = jIndex; j < len2; j++) rightP.push_back(num2[j]); } else{ leftP.clear(); rightP.clear(); for (int i = 0; i < iIndex; i++) leftP.push_back(num1[i]); if(jIndex > 0){ for(int j = 0; j < jIndex; j++) leftP.push_back(num2[j]); } for(int i = iIndex; i < len1; i++) rightP.push_back(num1[i]); if(jIndex < len2) for(int j = jIndex; j < len2; j++) rightP.push_back(num2[j]); } int leftV = *max_element(leftP.begin(), leftP.end()); int rightV = *min_element(rightP.begin(), rightP.end()); cout << "leftV : " << leftV << " " << "rightV : " << rightV << endl; median = 0.5*(leftV+rightV); } return median; } };
nums1和nums2都是按升序排列,其長度size = m+n。將前 size/2+1(size爲偶數) 或 (size+1)/2(size爲奇數) 進行排序,便可找到中位數。blog
Tip: 學習迭代器的使用,迭代器的增加;排序
class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { auto left = nums1.begin(); auto right = nums2.begin(); int size = nums1.size() + nums2.size(); //int sum = 0; int temp = 0; int temp1 = 0; for (int i = 0; i <= size / 2; i++) { if (left == nums1.end()) temp = *right++; else if (right == nums2.end()) temp = *left++; else if (*left < *right) temp = *left++; else temp = *right++; if (size / 2 - 1 == i) { temp1 = temp; } } if (size % 2 != 0) { return temp; } else { return (temp + temp1) / 2.0; } } };