Leetcode - Median of Two Sorted Arrays

**
Question:

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

**

My code:

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1 == null || nums2 == null)
            return 0;
        if (nums1.length == 0 && nums2.length == 0)
            return 0;
        int m = nums1.length;
        int n = nums2.length;
        if (m == 0)
            if (n % 2 == 1)
                return nums2[n / 2];
            else
                return ((double)nums2[n / 2] + (double)nums2[n / 2 - 1]) / 2.0;
        else if (n == 0)
            if (m % 2 == 1)
                return nums1[m / 2];
            else
                return ((double)nums1[m / 2] + (double)nums1[m / 2 - 1]) / 2.0;
        
        
        int indexOfNums1 = 0;
        int indexOfNums2 = 0;
        boolean isOutOfRange = false;
        int[] mergeArray = new int[m + n];
        for (int i = 0; i < m + n; i++) {
            
            if (indexOfNums1 < m && (nums1[indexOfNums1] < nums2[indexOfNums2] || isOutOfRange)) {
                mergeArray[i] = nums1[indexOfNums1];
                indexOfNums1++;
            }
            else {
                mergeArray[i] = nums2[indexOfNums2];
                if (indexOfNums2 < n - 1)
                    indexOfNums2++;
                else
                    isOutOfRange = true;
            }
        }
        
        if ((m + n) % 2 == 1)
            return mergeArray[(m + n) / 2];
        else
            return ((double)mergeArray[(m + n) / 2] + (double)mergeArray[(m + n) / 2 - 1]) / 2.0;
        
    }
    
    public static void main(String[] args) {
        Solution test = new Solution();
        int[] a = {100001};
        int[] b = {100000};
        System.out.println(test.findMedianSortedArrays(a, b));
    }
}

My test result:

Paste_Image.png

这次的难度是hard,但是我一看到就有了思路,然后花了十分钟写了出来。
这不就是归并排序(Merge Sort)的简单版本么。。。
给两个已排序好的数列,然后将它们合并,获得一个新的数列
来,复习下归并排序。
我自己创造的一个图书。
. . . . . . . . 一个array,用归并排序来处理
. . . . | . . . . 分成两个array,分别进行归并排序
. . | . . | . . | . . 对于每个子array,再次分成两个array,分别进行归并排序。
此时每个部分只有两个数字了, lo指向第一个,头。hi指向最后一个,也是第二个,尾。
于是进行简单的排序。完成了。退回到上步。
. . | . . | . . | . . 此时的子array都是已经排序好了的。于是将 1,2子array归并,3,4子array归并。
. . . . | . . . . 此时的两个子array也是已经排序好了的。于是将它们归并,得到最后的排序结果。
. . . . . . . .

然后归并排序的核心就是这次作业写的。
两个array,然后我先创建一个array长度是他们的长度和。
然后通过移动指针,将两个数组对应位置较小的拷贝进入mergeArray,然后指针再往前一格。这样,扫描(m + n)次就能完成了。
然后处理一些数组越界问题。就差不多。复杂度是 N * Log(N)

**
总结:
归并排序。
数组越界。
**

最近两次作业都是十几分钟写出来了。。。是我太强了吗?
我不觉得。我觉得是评测系统有问题。这两道题目正常人应该都半小时内就能做出来吧。
最近听了荔枝FM的一个广播。额,首先声明,我绝对不是做广告的人。
很感动。然后那么一句话。
**
其实我也是一个普通人啊。
**
打到我内心了。
小说世界里, 泰广,米可,最后能破镜重圆。
现实世界里,会有这般失而复得的事吗?
所以,确定你想要的,然后坚持下去。
读者们肯定看不懂我说的这些话,但你呢,应该看得懂吧。
我愿意为你改变很多,放弃很多。
你也愿意为我忍耐很多,担心很多。
异地异国实在是太难熬,但熬出头了呢。
如果因为那么一件件的事,咱们最终放弃。不知道你会怎么想。
我的话,一定会有新的女朋友,家庭。
但这份对你的遗憾,会陪伴我,直到进入棺材。

Anyway, Good luck, Richardo!

My code:

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1 == null || nums2 == null) {
            return -1;
        }
        else if (nums2.length < nums1.length) {
            return findMedianSortedArrays(nums2, nums1);
        }
        else if (nums2.length == 0) {
            return -1;
        }
        
        
        int m = nums1.length;
        int n = nums2.length;
        
        int half = (m + n + 1) / 2;
        int imin = 0;
        int imax = m;
        while (imin <= imax) {
            int i = (imax + imin) / 2;
            int j = half - i;
            if (i - 1 >= 0 && j < n && nums1[i - 1] > nums2[j]) {
                imax = i - 1;
            }
            else if (j - 1 >= 0 && i < m && nums2[j - 1] > nums1[i]) {
                imin = i + 1;
            }
            else {
                int left = 0;
                if (i == 0) {
                    left = nums2[j - 1];
                }
                else if (j == 0) {
                    left = nums1[i - 1];
                }
                else {
                    left = Math.max(nums1[i - 1], nums2[j - 1]);
                }
                
                if ((m + n) % 2 == 1) {
                    return left;
                }
                
                int right = 0;
                if (i == m) {
                    right = nums2[j];
                }
                else if (j == n) {
                    right = nums1[i];
                }
                else {
                    right = Math.min(nums1[i], nums2[j]);
                }
                
                return (left + right) / 2.0;
            }
        }
        return -1;
    }
    
    public static void main(String[] args) {
        Solution test = new Solution();
        int[] nums1 = new int[]{1,2};
        int[] nums2 = new int[]{3,4,5,6};
        double ret = test.findMedianSortedArrays(nums1, nums2);
        System.out.println(ret);
    }
}

reference:
https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation/2

这道题目实在是太恶心了。弄了一个多小时。
corner case 太多了。。。

看下讲解,思路清晰了很多。但是还是调了很久很久。
最大的问题是,得把短的作为切割的第一数组,即, i

因为如果切长的,作为i
那么 j很有可能变成负数,会出现错误。
如果切短的,就不会用这个问题。

还有个注意的地方就是:
half = (m + n + 1) / 2;
这样保证,如果 m + n 是偶数,
那么左右部分个数相等。
如果是奇数,那么左边会多一个。

而且imax = m 而不是 m - 1,真的求中点。
如果m是奇数,就是正中点。如果m是偶数,是中间两个数右边那个。
这些正好都是我们需要的特性。

实在是太恶心了。

加油!

Anyway, Good luck, Richardo! -- 09/01/2016

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容