从0打卡leetcode之day 5 ---两个排序数组的中位数

简介: 前言我靠,才坚持了四天,就差点不想坚持了。不行啊,我得把leetcode上的题给刷完,不然怕是不好进入bat的大门。题目描述给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。

前言

我靠,才坚持了四天,就差点不想坚持了。不行啊,我得把leetcode上的题给刷完,不然怕是不好进入bat的大门。

题目描述

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。
请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。你可以假设 nums1 和 nums2 均不为空。

示例
nums1 = [1, 3]
nums2 = [2]

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

中位数是 (2 + 3)/2 = 2.5``

解题

最简单粗暴的就是把这两个数组头尾连接起来,然后重新给他们排序一下,冒泡排序相信你信手拈来,当然,你也可以装逼用快速排序。

但是,如果这样子做的话,题目给你的有序数组就没啥用了,和无序一个样,所以这样做是不行的。题目要求是时间复杂度不能超过O(log(n+m)),说实话,这个复杂度我是不知道怎么做好,我的做法时间复杂度是O(n+m)。

具体是这样的

居然两个数组都是有序的了,我们可以再弄一个中间数组,然后把两个数组各自从数组头开始比较,哪个元素小,我们就把它存在中间数组。然后接下下一个元素一直比较下去。

我还是直接上代码吧。如下:

    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
            int m = nums1.length;
            int n = nums2.length;
            int t = m + n;//总长度
            int temp[] = new int[t];
            int i  = 0, j = 0, k = 0;
            double obj;//用来存目标值

            while(i < m && j < n){
                //把数组中比较小的值转移到temp数组中
                if(nums1[i] < nums2[j]){
                    temp[k++] = nums1[i++];
                }else{
                    temp[k++] = nums2[j++];
                }
            }
            //把剩余的转移过去
        while (i < m){
                temp[k++] = nums1[i++];
        }
        while(j < n){
                temp[k++] = nums2[j++];
        }
        //两个数组的总个数是奇数还是偶数
        if(t % 2 == 0){//偶数
                obj = (temp[t/2] + temp[(t-1)/2]) / 2.0;
        }else{
                obj = temp[t/2];
        }

        return obj;
    }

虽然时间复杂度是O(n+m),但是提交的时候居然通过了,而且还打败了93%的人。

不过,这里还可以在优化,把时间复杂度降低到O((n+m)/2)。
就是说其实我们不用给整个temp数组排序,我们只要求出前面一半的数组元素就可以知道中间那个元素了,。例如不管一共是偶数个元素还是奇数个元素,我们让temp存到下标为t/2就可以了。然后再来判断t是奇数还是偶数…..

例如上面两个示例,示例1一共有三个元素,那么temp[t/2]=temp[1]=2。然后直接把temp[t/2]=temp[1]取出来返回就可以了。

示例2一共有4个元素,那么temp[t/2]=temp[2]=3。由于是偶数,我们直接把temp[t/2]=3和temp[t/2-1]=2这两个元素取出来处理之后返回就可以了。

至于代码这么写,我就不写了。知道有这么一回事就可以了。

如果你坚持想要O(log(n+m))的时间复杂度,那么可以看官方给的答案:

链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/

目录
相关文章
|
27天前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
37 0
|
22天前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
17 4
|
22天前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
13 0
Leetcode第三十三题(搜索旋转排序数组)
|
22天前
|
算法 C++
Leetcode第53题(最大子数组和)
这篇文章介绍了LeetCode第53题“最大子数组和”的动态规划解法,提供了详细的状态转移方程和C++代码实现,并讨论了其他算法如贪心、分治、改进动态规划和分块累计法。
47 0
|
22天前
|
C++
【LeetCode 12】349.两个数组的交集
【LeetCode 12】349.两个数组的交集
13 0
|
3月前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
3月前
|
算法
LeetCode第81题搜索旋转排序数组 II
文章讲解了LeetCode第81题"搜索旋转排序数组 II"的解法,通过二分查找算法并加入去重逻辑来解决在旋转且含有重复元素的数组中搜索特定值的问题。
LeetCode第81题搜索旋转排序数组 II
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
52 6
|
3月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
102 2