4.寻找两个正序数组的中位数-java实现

第四题:寻找两个正序数组的中位数

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:

nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/check-permutation-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

V1版本

既然有是序的那就好办了,题目说了不会同时为空,就说明可能会有一个为空的情况
所以可分为两种情况进行
1,有一个数组为空的情况
1.1 数组长度为奇数,中位数就是中间那个数
例[1,2,3,4,5],数组长度为5,index为2,应该取出下标为2的数(3)为中位值
1.2 数组长度为偶数,
例[1,2,3,4],数组长度为4,index为2,应该取出下标为 1,2两个数(2,3),取平均值

2, 两个数组都不为空
两个数组都不为空且有序,先获取两个数据的总长度算出中位数出现的位置(总长度/2)
例:
num1[1,3,5],num2[2],这时总长度为4
num1[1,3,5],num2[2,4],这时总长度为5
不管是哪种形式,我们都是循环取两个数组中的值去比对,值更小的数组下标向后滑动一位
最终都去获取下标为 (总长度/2)和(总长度/2 - 1) 下标的值
如:
第一对数组我们取出值 [2,3]
第二对数组我们取出值 [2,3]
由于一第组数组总长度为偶数,对我们将取这两个数的平均值(2.5)进行返回
第二组为奇数,我们直接返回后面那个值(即3)
注意:要考虑边界情况,小心数组越界
代码如下:

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        /**
         * 两个数数组不会同时为空,只有一个数组的时候执行效率更高
         */
        if (nums1 == null || nums1.length == 0) {
            return findMedianSortedArrays(nums2);
        }
        if (nums2 == null || nums2.length == 0) {
            return findMedianSortedArrays(nums1);
        }
        // 定义两个数组初始下标值
        int numIndex1 = 0, numIndex2 = 0;
        // 总数组长度
        int totalLength = nums1.length + nums2.length;
        // 是否为奇数
        boolean isOddNumber = totalLength % 2 == 1;
        /**
         * 获取两个中位数的位置,
         * 如果是积数位,则后续直接返回endIndex
         * 如果是偶数位,后续返回两个坐标对应值的平均值
         */
        int endIndex = totalLength/2;
        int startIndex = endIndex - 1;
        int startValue = 0;
        int endValue = 0;

        // 临时变量
        int value;
        for (int i = 0; i <= endIndex; i++) {
            if (numIndex2 >= nums2.length) {
                value = nums1[numIndex1];
                numIndex1++;
            } else if (numIndex1 >= nums1.length) {
                value = nums2[numIndex2];
                numIndex2++;
            } else if (nums1[numIndex1] < nums2[numIndex2]) {
                value = nums1[numIndex1];
                numIndex1++;
            } else {
                value = nums2[numIndex2];
                numIndex2++;
            }

            if (i == startIndex) {
                startValue = value;
            } else if (i == endIndex) {
                endValue = value;
            }
        }
        return isOddNumber? endValue : getAverage(startValue, endValue);
    }

    /**
     * 有一条数组为空的情况
     */
    public double findMedianSortedArrays(int[] nums) {
        int index = nums.length / 2;
        /**
         * 数组长度为奇数,中位数就是中间那个数
         * 例[1,2,3,4,5],数组长度为5,index为2,应该取出下标为2的数(3)为中位值
         */
        if (nums.length % 2 == 1) {
            return nums[index];
        }
        /**
         * 数组长度为偶数,
         * 例[1,2,3,4],数组长度为4,index为2,应该取出下标为 1,2两个数(2,3),取平均值
         */
        return getAverage(nums[index - 1], nums[index]);
    }

    /**
     * 获取平均值
     */
    private static double getAverage(int a, int b) {
        return ((double)a + (double)b) / 2;
    }

这道题是让我困惑的是难度竟然是:困难,但是出奇的好实现不过我的实现代码很长,在去看看大佬们的实现思路


image.png

V2版本

去看了一下官方的实现,由于官方的在数组总长度为偶数时,去遍历了两次来获取结果,我认为这种方式还是不可取


image.png

V2版本想继续优化的点就是在两个数组极不平衡的时候
例:num1[1,3,4,5,7,9,11,13,15,17,19,.....],num2[2]
的时候,其实不需要继续向下循环,可以快速的获取结果,不过代码实现可能会更复杂,可读性会变差,
暂时没有好的方式实现,V2版本先暂停

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