LeetCode #4 (A nice explanation from MissMary)

Given a sorted array A with length m, we can split it into two part:

{ A[0], A[1], ... , A[i - 1] } | { A[i], A[i + 1], ... , A[m - 1] }

All elements in right part are greater than elements in left part.

The left part has "i" elements, and right part has "m - i" elements.

There are "m + 1" kinds of splits. (i = 0 ~ m)

When i = 0, the left part has "0" elements, right part has "m" elements.

When i = m, the left part has "m" elements, right part has "0" elements.

For array B, we can split it with the same way:

{ B[0], B[1], ... , B[j - 1] } | { B[j], B[j + 1], ... , B[n - 1] }

The left part has "j" elements, and right part has "n - j" elements.

Put A‘s left part and B‘s left part into one set. (Let‘s name this set "LeftPart")

Put A‘s right part and B‘s right part into one set. (Let‘s name this set"RightPart")

            LeftPart           |            RightPart
{ A[0], A[1], ... , A[i - 1] } | { A[i], A[i + 1], ... , A[m - 1] }
{ B[0], B[1], ... , B[j - 1] } | { B[j], B[j + 1], ... , B[n - 1] }

If we can ensure:

 1) LeftPart‘s length == RightPart‘s length (or RightPart‘s length + 1)

 2) All elements in RightPart are greater than elements in LeftPart.

then we split all elements in {A, B} into two parts with eqaul length, and one part is

always greater than the other part. Then the median can be easily found.

To ensure these two condition, we just need to ensure:

 (1) i + j == m - i + n - j (or: m - i + n - j + 1)

     if n >= m, we just need to set: 

           i = 0 ~ m, j = (m + n + 1) / 2 - i

 (2) B[j - 1] <= A[i] and A[i - 1] <= B[j]

     considering edge values, we need to ensure:

           (j == 0 or i == m or B[j - 1] <= A[i]) and 

               (i == 0 or j == n or A[i - 1] <= B[j])

So, all we need to do is:

 Search i from 0 to m, to find an object "i" to meet condition (1) and (2) above.

And we can do this search by binary search. How?

If B[j0 - 1] > A[i0], then the object "ix" can‘t be in [0, i0]. Why?

 Because if ix < i0, then jx = (m + n + 1) / 2 - ix > j0, 

 then B[jx - 1] >= B[j0 - 1] > A[i0] >= A[ix]. This violates

 the condition (2). So ix can‘t be less than i0.

And if A[i0 - 1] > B[j0], then the object "ix" can‘t be in [i0, m].

So we can do the binary search following steps described below:

1. set imin, imax = 0, m, then start searching in [imin, imax]

2. i = (imin + imax) / 2; j = (m + n + 1) / 2 - i

3. if B[j - 1] > A[i]: continue searching in [i + 1, imax]
   elif A[i - 1] > B[j]: continue searching in [imin, i - 1]
   else: bingo! this is our object "i"

When the object i is found, the median is:

max(A[i - 1], B[j - 1]) (when m + n is odd)

or (max(A[i - 1], B[j - 1]) + min(A[i], B[j])) / 2 (when m + n is even)

  

Below is the accepted code:

def median(A, B):
    m, n = len(A), len(B)

    if m > n:
        A, B, m, n = B, A, n, m

    imin, imax, half_len = 0, m, (m + n + 1) / 2
    while imin <= imax:
        i = (imin + imax) / 2
        j = half_len - i
        if j > 0 and i < m and B[j - 1] > A[i]:
            imin = i + 1
        elif i > 0 and j < n and A[i - 1] > B[j]:
            imax = i - 1
        else:
            if i == 0:
                num1 = B[j - 1]
            elif j == 0:
                num1 = A[i - 1]
            else:
                num1 = max(A[i - 1], B[j - 1])

            if (m + n) % 2 == 1:
                return num1

            if i == m:
                num2 = B[j]
            elif j == n:
                num2 = A[i]
            else:
                num2 = min(A[i], B[j])

            return (num1 + num2) / 2.0
时间: 2024-10-05 11:21:42

LeetCode #4 (A nice explanation from MissMary)的相关文章

[LeetCode]题解(python):031-Next Permutation

题目来源 https://leetcode.com/problems/next-permutation/ Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearrange it as the lowest possible

LeetCode 225 Implement Stack using Queues(用队列来实现栈)(*)

翻译 用队列来实现栈的例如以下操作. push(x) -- 将元素x加入进栈 pop() -- 从栈顶移除元素 top() -- 返回栈顶元素 empty() -- 返回栈是否为空 注意: 你必须使用一个仅仅有标准操作的队列. 也就是说,仅仅有push/pop/size/empty等操作是有效的. 队列可能不被原生支持.这取决于你所用的语言. 仅仅要你仅仅是用queue的标准操作,你能够用list或者deque(double-ended queue)来模拟队列. 你能够如果全部的操作都是有效的(

[LeetCode]题解(python):064-Minimum Path Sum

题目来源: https://leetcode.com/problems/minimum-path-sum/ 题意分析: 给定一个m×n的非负矩阵,找到一条路使得从(0,0)到(m - 1,n - 1)经过的所有数字的和最小(类似上两题,只能向下和向上). 题目思路: 和上一题类似,用一个二维矩阵a[i][j]代表从(0,0)到(i,j)的最小和.那么a[i][j] = min(a[i-1][j],a[i][j -1]) + nums[i][j].那么这题也是一个动态规划问题,只需要把a的整个表打

[LeetCode] Triangle(&#39;Bottom-up&#39; DP)

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. For example, given the following triangle [ [2], [3,4], [6,5,7], [4,1,8,3] ] The minimum path sum from top to bottom is 11 (i

Pascal&#39;s Triangle leetcode java(杨辉三角)

题目: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Return [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] 题解:既然讲到了Pascal‘s Triangle,即杨辉三角.那么就先去Wikipedia上面复习一下杨辉三角吧:”杨辉三角形,又称賈憲三角形.帕斯卡三角形.海亚姆三角形,是二项式係數在的

[LeetCode]题解(python):122-Best Time to Buy and Sell Stock II

题目来源: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ 题意分析: 和上题类似,给定array,代表第i天物品i的价格.如果可以交易无数次(手上有物品不能买),问最高利润. 题目思路: 记录当前最小值,如果遇到array[i]  < min,那么加上当前的最大值:更新min. 代码(python): class Solution(object): def maxProfit(self, prices): &quo

leetcode题解:Valid Parentheses(栈的应用-括号匹配)

题目: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]&

LeetCode:Longest Substring Without Repeating Characters(最长不重复子串)

题目链接 Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest

Linked List Cycle leetcode II java (寻找链表环的入口)

题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up: Can you solve it without using extra space? 题解: 这个连同I都是很经典的题啦,刷CC150时候就折磨了半天. 其实就推几个递推公式就好..首先看图(图引用自CC150): 从链表起始处到环入口长度为:a,从环入口到Faster和Sl