【leetcode長跑】開個頭 Median of Two Sorted Arrays

NO IMAGE

大家好,我叫張小豬。

自第一篇收集向的文章釋出後,近 1 年半沒更新這個專欄了。最近面試中發現將近 60% 的候選人對於 bubble sort 面露難色,於是心悸於自己也忘記了很多大學的內容,遂有時間就寫寫 leetcode 好了,也不荒廢當初開了這個地方。路途遙遠,且行且珍惜。

今天是 Algorithms 分類中第一個 Hard 的,叫做 Median of Two Sorted Arrays。描述如下:

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)).

題目描述內容比較少,大意就是提供兩個有序陣列,需要找到這兩個陣列的中間值。
給了兩個例子:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2   3)/2 = 2.5

看完描述和例子後,第一反應就是合併兩個陣列,然後找到中間位置即可。不過這樣需要兩個陣列各掃一遍,然而我們的目的只是要取到中間值,似乎並不用完整的掃一遍。那就按照這個思路看看吧。

首先,根據例子可以看出,偶數和奇數個長度對於最終結果的計算是會有影響的。即奇數個我們能直接取到中間值,而偶數個需要取到最靠近中間的兩個值然後取平均數。那麼也就意味著,我們最終要記錄的值可能是兩個。
然後,由於兩個陣列都是有序的,那麼他們的中間值索引其實就是做合併操作過程中的索引。

基於以上兩點,我們得到要做的事情是:

計算中間值的索引
做有序陣列合並
得到結果

那麼開始寫程式碼吧(吐槽一下 leetcode 的編輯器並不太好用):

var findMedianSortedArrays = function(nums1, nums2) {
    var sumLen = nums1.length   nums2.length,
        targetLen = sumLen >>> 1,
        loop = targetLen   1,
        i = 0, // for num1 index
        j = 0, // for num2 index
        x, y;

    while (loop--) {
        x = y;
        if (nums1[i] === undefined) {
            y = nums2[j  ]
        } else if (nums2[j] === undefined) {
            y = nums1[i  ];
        } else if (nums1[i] < nums2[j]) {
            y = nums1[i  ];
        } else {
            y = nums2[j  ];
        }
    }

    return targetLen << 1 === sumLen ? (x   y) / 2 : y;
};

Test case 通過後連續提交了幾次,時間在 beats 85% 左右浮動,最低 72%,最高 97%,算是可以接受吧。

想想最近快要到雙 11 了,別人都是買包買衣買香水、傢俱電器旅行飛,小豬隻是連著關注了幾天顯示卡和 CPU,還捨不得剁手。哎,說多了都是淚啊,還是洗洗豬鼻子睡了吧。。。