1. 程式人生 > >LeetCode 演算法學習(3)

LeetCode 演算法學習(3)

題目描述

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)).
You may assume nums1 and nums2 cannot be both empty.

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

The median is 2.0

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

The median is (2 + 3)/2 = 2.5

題目大意

給出兩個排好序的陣列,找出它們的中值。

思路分析

這是一道經典的分而治之的題目,將兩個有序陣列分成兩半,找出數值小的部分的最大值和數值大的部分的最小值,中值就等於他們的平均數((m+n)為偶數時),或者其中之一((m+n)為奇數)。時間複雜度為O(log n),空間複雜度為O(1)。

關鍵程式碼

    double findMedianSortedArrays
(vector<int>& nums1, vector<int>& nums2) { int m = nums1.size(); int n = nums2.size(); if (m < n) { // ensure that m >= n vector<int> temp = nums1; nums1 = nums2; nums2 = temp; m = nums1.size(); n =
nums2.size(); } int low = 0, high = n, half = (m+n+1)/2; while (low <= high) { // divide in two part int med1 = (low+high)/2; int med2 = half-med1; if (med1 < high && nums1[med2-1] > nums2[med1]) { // median in the right part low = med1 + 1; } else if (med1 > low && nums2[med1-1] > nums1[med2]) { // median in the left part high = med1 - 1; } else { // max of left part int maxLeft = 0; if (med1 == 0) maxLeft = nums1[med2-1]; else if (med2 == 0) maxLeft = nums2[med1-1]; else maxLeft = (nums2[med1-1] > nums1[med2-1]) ? nums2[med1-1] : nums1[med2-1]; if ((m+n)%2 == 1) return maxLeft; // min of the right part int minRight = 0; if (med1 == n) minRight = nums1[med2]; else if (med2 == m) minRight = nums2[med1]; else minRight = (nums1[med2] > nums2[med1]) ? nums2[med1] : nums1[med2]; return (maxLeft + minRight)/2.0; } } return 0; }

總結

這道題給我們提供了分而治之的思想,在查詢兩部分的最大(小)值時採用二分法,加快了演算法的速度。而在處理m+n為奇偶數的時候需要小心。
採用合併再查詢也可以,時間複雜度變為O(m+n),但是這就沒有用到分而治之的思想了。