<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          LeetCode刷題實戰(zhàn)4:兩個正序數(shù)組的中位數(shù)

          共 1975字,需瀏覽 4分鐘

           ·

          2020-08-08 23:54



          算法的重要性,我就不多說了吧,想去大廠,就必須要經(jīng)過基礎(chǔ)知識和業(yè)務(wù)邏輯面試+算法面試。所以,為了提高大家的算法能力,這個公眾號后續(xù)每天帶大家做一道算法題,題目就從LeetCode上面選 !


          今天和大家聊的問題叫做尋找兩個正序數(shù)組的中位數(shù),這道題很有意思,我們先來看題面:

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


          You may assume nums1 and nums2 cannot be both empty.


          https://leetcode-cn.com/problems/median-of-two-sorted-arrays


          翻譯


          給定兩個大小為 m 和 n 的正序(從小到大)數(shù)組 nums1 和 nums2。

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

          你可以假設(shè) nums1 和 nums2 不會同時為空。


          樣例


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


          方法一:二分查找

          給定兩個有序數(shù)組,要求找到兩個有序數(shù)組的中位數(shù),最直觀的思路有以下兩種:

          使用歸并的方式,合并兩個有序數(shù)組,得到一個大的有序數(shù)組。大的有序數(shù)組的中間位置的元素,即為中位數(shù)。


          不需要合并兩個有序數(shù)組,只要找到中位數(shù)的位置即可。由于兩個數(shù)組的長度已知,因此中位數(shù)對應(yīng)的兩個數(shù)組的下標之和也是已知的。維護兩個指針,初始時分別指向兩個數(shù)組的下標 00 的位置,每次將指向較小值的指針后移一位(如果一個指針已經(jīng)到達數(shù)組末尾,則只需要移動另一個數(shù)組的指針),直到到達中位數(shù)的位置。


          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] 進行比較
          ?????????* 這里的 "/" 表示整除
          ?????????* nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共計 k/2-1 個
          ?????????* nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共計 k/2-1 個
          ?????????* 取 pivot = min(pivot1, pivot2),兩個數(shù)組中小于等于 pivot 的元素共計不會超過 (k/2-1) + (k/2-1) <= k-2 個
          ?????????* 這樣 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ù)的個數(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;
          ????????????}
          ????????}
          ????}
          }


          本題還有第2個方法:劃分數(shù)組?,大家有興趣的自己去leetcode學(xué)習(xí)一下,今天文章就不說了,這個比較有難度 。


          如果喜歡本文,請順手點個贊或者轉(zhuǎn)發(fā)吧。


          上期推文:

          LeetCode刷題實戰(zhàn)1:在數(shù)組上遍歷出花樣

          LeetCode刷題實戰(zhàn)2:用鏈表模擬加法

          LeetCode刷題實戰(zhàn)3:最長不重復(fù)子串


          瀏覽 35
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  秋霞影音先锋 | 色吊丝最新永久网址大全 | 大荫蒂视频另类XX | 伊人精品综合 | 黑人操|