算法导论 Exercises 9.3-8 - GoAgent - 博客园



算法导论 Exercises 9.3-8 - GoAgent - 博客园

Problem Description:

Let X[1...n] and Y[1...n] be two arrays, each containing n numbers already in sorted order.

Give an O(lgn)-time algorithm to find the median of all 2n elements in array X and Y.

问题描述:

X和Y是两个长度均为n的已排序数组,现要求以O(lgn)的时间复杂度找到两个数组中所有2n个数的中值。

(注:这里中值被定义为:对于奇数个数,排序后中间那个,或者对于偶数个数,排序后中间两个数下标较小的那个)

问题升级:

题目中假设了两个数组长度相等,并且找中值。

这里修改一下题目,假设两个数组长度不一定相等,分别为m和n,要求以O(lgm + lgn)的时间复杂度找到m+n个数中的第i个数。

先解决一般情况,再将原题作为一种特殊情况来处理。

 

解决方案:

如上图所示的两个已排序数组(假设为单调非减),其中aMid = (aBeg + aEnd) / 2是数组中值的下标。

{a1}是数组a中a[aBeg]至a[aMid]段的元素的集合,{a2}是数组a中a[aMid + 1]至a[aEnd]段的元素的集合。同理{b1}、{b2}如图所示。

 

假设a[aMid] <= b[bMid](a[aMid] > b[bMid]的情况与之类似),则有:

{a1}<={a2} {a1}<={b2}

即对于{a1}中的任意元素,在a、b中不小于它的数至少有(aEnd - aMid) + (bEnd - bMid) + 1个

所以对于{a1}中的任意元素,在a、b中小于它的数至多有

[(aEnd - aBeg + 1) + (bEnd - bBeg + 1)] - [(aEnd - aMid) + (bEnd - bMid) + 1]

=(aMid - aBeg) + (bMid - bBeg) + 1个......①

同理,{b2}>={b1} {b2}>={a1}

对于{b2}中的任意元素,在a、b中不大于它的数至少有(bMid - bBeg) + (aMid - aBeg) + 1

=(aMid - aBeg) + (bMid - bBeg) + 1个......②

由①、②可知:

如果i <= (aEnd - aMid) + (bEnd - bMid) + 1,那第i个数一定不在{b2}中。

此时只需在{a1}、{a2}、{b1}中继续找第i个数就可以了。

(当i == (aEnd - aMid) + (bEnd - bMid) + 1时,只有在a[aMid] == b[bMid]时,第i个数等于a[aMid]或者b[bMid],

此时虽然b[bMid]在{b2}中,但由于a[aMid]不在{b2}中,所以不影响我们"第i个数一定不在{b2}中"的判断)

如果i > (aEnd - aMid) + (bEnd - bMid) + 1,那第i个数一定不在{a1}中。

此时只需在{a2}、{b1}、{b2}中继续找第i - (aMid - aBeg + 1)个数就可以了。

同理在a[aMid] > b[bMid]时,可以得出类似的结论,只是a、b两个数组的角色互换。

 

由上面的分析,每次递归可以丢弃掉其中一个数组一半的元素直至递归结束。

递归结束的条件是其中一个数组已经为空,此时在另外一个数组里面直接找第i个数就可以了。

因此本算法的时间复杂度是O(lgm + lgn)的。


Read full article from 算法导论 Exercises 9.3-8 - GoAgent - 博客园


No comments:

Post a Comment

Labels

Algorithm (219) Lucene (130) LeetCode (97) Database (36) Data Structure (33) text mining (28) Solr (27) java (27) Mathematical Algorithm (26) Difficult Algorithm (25) Logic Thinking (23) Puzzles (23) Bit Algorithms (22) Math (21) List (20) Dynamic Programming (19) Linux (19) Tree (18) Machine Learning (15) EPI (11) Queue (11) Smart Algorithm (11) Operating System (9) Java Basic (8) Recursive Algorithm (8) Stack (8) Eclipse (7) Scala (7) Tika (7) J2EE (6) Monitoring (6) Trie (6) Concurrency (5) Geometry Algorithm (5) Greedy Algorithm (5) Mahout (5) MySQL (5) xpost (5) C (4) Interview (4) Vi (4) regular expression (4) to-do (4) C++ (3) Chrome (3) Divide and Conquer (3) Graph Algorithm (3) Permutation (3) Powershell (3) Random (3) Segment Tree (3) UIMA (3) Union-Find (3) Video (3) Virtualization (3) Windows (3) XML (3) Advanced Data Structure (2) Android (2) Bash (2) Classic Algorithm (2) Debugging (2) Design Pattern (2) Google (2) Hadoop (2) Java Collections (2) Markov Chains (2) Probabilities (2) Shell (2) Site (2) Web Development (2) Workplace (2) angularjs (2) .Net (1) Amazon Interview (1) Android Studio (1) Array (1) Boilerpipe (1) Book Notes (1) ChromeOS (1) Chromebook (1) Codility (1) Desgin (1) Design (1) Divide and Conqure (1) GAE (1) Google Interview (1) Great Stuff (1) Hash (1) High Tech Companies (1) Improving (1) LifeTips (1) Maven (1) Network (1) Performance (1) Programming (1) Resources (1) Sampling (1) Sed (1) Smart Thinking (1) Sort (1) Spark (1) Stanford NLP (1) System Design (1) Trove (1) VIP (1) tools (1)

Popular Posts