| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> ??思维导图整理大厂面试高频数组10: 3种方法彻底解决中位数问题 力扣4?? -> 正文阅读 |
|
[Java知识库]??思维导图整理大厂面试高频数组10: 3种方法彻底解决中位数问题 力扣4?? |
题目链接: https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 力扣上对于此题的各种思想的讲解已经非常详细了(图文并茂), 但是他们对于自己的代码几乎没什么补充, 大多都是思想讲解完成直接就上代码了, 但是本题即使思想理解了, 在代码的理解上还是有难度的, 所以本文重点对 代码的理解 做了详细的解释. 0.导图整理1.常规思想的改进: 假合并/奇偶合并本题的常规思想还是挺简单的: 使用归并的方式, 合并两个有序数组, 得到一个大的有序数组. 大的有序数组的中间位置的元素, 即为中位数. 但是这种思路的时间复杂度是 O(m+n), 空间复杂度是 O(m+n), 面试的时候, 面试官肯定不会满意这样的答案的. 因此我们必须想办法将算法进行优化, 这里先介绍一种简单的优化方式, 就是 假合并, 即我们并不需要真的合并两个有序数组, 只要找到中位数的位置即可. 它的思想并不复杂, 由于两个数组的长度已知, 因此中位数对应的两个数组的下标之和也是已知的。维护两个指针, 初始时分别指向两个数组的下标0的位置, 每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针), 直到到达中位数的位置. 通过这种 假合并 的方式, 我们可以成功的将空间复杂度优化到了O(1), 但是对于时间复杂度并没有什么优化. 讲解这个方法的目的并不是为了让大家掌握此方法, 而是为了让大家掌握此方法的一些巧妙的 优化方式. 此方法理解是比较容易的, 但是真正写代码时候还是很有挑战的, 你不仅要考虑奇偶的问题, 更要考虑 一个数组遍历结束后 的各种边界问题, 其实很多困难题就是难在了对于边界的处理上面了. 此方法的一个优化点就是 将奇偶两种情况合并到了一起, 具体思想如下: 这种思想是很有必要的, 对于数组来说, 我们经常会遇到奇偶的两种情况处理, 如果想办法将他们合并在一起, 那代码写起来就是非常顺畅和整洁. 另一种合并的思想是: 我们可以在奇数的时候, 在末尾等处添加一个占位符#等, 这样也是可以将奇数合并成偶数的情况的. 此方法的另一个优化点就是 通过在if条件中加入大量的限制条件, 从而实现了对于各种边界问题的处理, 这也是一种很重要的思想. 此方法的时间复杂度相对于下面两种思想还是太高了, 大家不用特意掌握此方法, 但是这两个优化的思想还是很重要的, 要好好的理解一下. 接下来我们就来详细讲解两个时间复杂度超低的算法代码思想. 2.寻找第k小数 代码详解关于本题转换为 第k小数 的思想, 就不用纠结怎么想到的了, 大家就安心的理解思想和代码并将它记在脑中就可以了. 其实关于这个算法的思想并不是太难理解, 主要就是根据两个数的三种比较结果, 不断地去除不满足的元素的过程. 我认为这个思想最难的点在于 三种特殊情况的处理, 我们能否想到这三种情况, 并将他们完美的融入到代码之中, 我感觉这才是真正的难点所在. 接下来我们来详细解读此思想的代码实现. 最开始对于奇数和偶数的两种情况进行了判断, 其实是可以将两种情况合并的, 只需要在奇数时求两次同样的k就可以了. 接下来处理了三种特殊情况中的两种特殊情况: 一个数组为空 和 k=1. 下面的几个定义就非常重要了, 一定要弄清这些定义的含义, 才能更轻松的理解代码. index1, index2作为数组的起始点的下标, 初值都是0, 但是随着两个数组不断被删除元素, 这两个起始点也是在不断的进行变化, 具体变化方式就是 index1 = newIndex1 + 1, 因为在删除元素的时候 连同比较位置也一同删去了, 所以新的开始是 比较位置 的后一位. newindex1, newindex2作为比较点就是图中被框中的两个数的下标, 它的赋值过程就涉及到了 最后一个边界情况. 因为当一个数组较短时, 其中一个比较点可能已经到达了数组的最后, 所以它的值是 两种情况下较小的那个数. 接下来就是根据两个比较点的大小来进行不同的操作过程了, 这里最难理解的点就是 k -= (newIndex1 - index1 + 1), 也就是减去元素的个数问题了. 我们根据上面的图来举例, 图中index1的值为0, newindex1的值经过计算为1, 通过比较后, 可以看到 红色的数 就是被删除的数, 也就是两个, 所以我们需要在最后+1才是真实被删去的个数. 对于此类问题在确定最终个数的时候, 我们都可以通过这样的特例来决定代码的书写, 至此代码就全部讲解完成了. 3.理解中位数作用进行 划分数组最后这种思想的时间复杂度甚至比上面的还低, 上面的思想每一轮循环可以将查找范围减少一半,因此时间复杂度是O(log(m+n)), 但这种思想可以对确定的较短的数组进行二分查找, 所以它的时间复杂度是 O(log min(m,n)). 划分数组 正好和上面算法完全相反, 它的思想特别复杂, 但思想理解了, 代码写起来倒是没太大的难度, 所以我们重点说说它的思想. 首先我们要明白中位数的作用: 将一个集合划分为两个长度相等的子集, 其中一个子集中的元素总是大于另一个子集中的元素, 这种思想无论是在几个数组中都是适用的, 这就衍生出了下面的算法思想. 首先来讨论奇偶的两种不同情况下的不同划分方式. 然后在编写代码的时候, 由于计算机的取整操作, 我们是可以将这两种情况合并成一种代码书写方式的. 其中的i和j分别是两个数组的划分位置. 同样我们也会遇到复杂的边界问题, 但下面这种处理方式是真的非常优秀. 上面问题都考虑完了, 其实就可以写代码了, 但是我们需要进行两个条件的判断: B[j?1]≤A[i] 以及A[i?1]≤B[j], 为了优化代码, 经过分析后, 我们发现这两种情况是可以等价转换的. 也就是只需要进行一个条件的判断即可. 代码中有个注意点就是java中的三目运算符? : 在Python中是没有引入这个符号的, 但是Python利用了已有的关键字if…else实现了这个功能. 源码Python:
java:
我的更多精彩文章链接, 欢迎查看 各种电脑/软件/生活/音乐/动漫/电影技巧汇总(你肯定能够找到你需要的使用技巧) 力扣算法刷题 根据思维导图整理笔记快速记忆算法重点内容(欢迎和博主一起打卡刷题哦) 计算机专业知识 思维导图整理 最值得收藏的 Python 全部知识点思维导图整理, 附带常用代码/方法/库/数据结构/常见错误/经典思想(持续更新中) 最值得收藏的 C++ 全部知识点思维导图整理(清华大学郑莉版), 东南大学软件工程初试906科目 最值得收藏的 计算机网络 全部知识点思维导图整理(王道考研), 附带经典5层结构中英对照和框架简介 最值得收藏的 算法分析与设计 全部知识点思维导图整理(北大慕课课程) 最值得收藏的 数据结构 全部知识点思维导图整理(王道考研), 附带经典题型整理 最值得收藏的 人工智能导论 全部知识点思维导图整理(王万良慕课课程) 最值得收藏的 数值分析 全部知识点思维导图整理(东北大学慕课课程) 最值得收藏的 数字图像处理 全部知识点思维导图整理(武汉大学慕课课程) 红黑树 一张导图解决红黑树全部插入和删除问题 包含详细操作原理 情况对比 各种常见排序算法的时间/空间复杂度 是否稳定 算法选取的情况 改进 思维导图整理 人工智能课件 算法分析课件 Python课件 数值分析课件 机器学习课件 图像处理课件 考研相关科目 知识点 思维导图整理 考研经验–东南大学软件学院软件工程(这些基础课和专业课的各种坑和复习技巧你应该知道) 东南大学 软件工程 906 数据结构 C++ 历年真题 思维导图整理 最值得收藏的 考研高等数学 全部知识点思维导图整理(张宇, 汤家凤), 附做题技巧/易错点/知识点整理 最值得收藏的 考研线性代数 全部知识点思维导图整理(张宇, 汤家凤), 附带惯用思维/做题技巧/易错点整理 考研思修 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理 考研近代史 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理 考研马原 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理 考研数学课程笔记 考研英语课程笔记 考研英语单词词根词缀记忆 考研政治课程笔记 Python相关技术 知识点 思维导图整理 Numpy常见用法全部OneNote笔记 全部笔记思维导图整理 Pandas常见用法全部OneNote笔记 全部笔记思维导图整理 Matplotlib常见用法全部OneNote笔记 全部笔记思维导图整理 PyTorch常见用法全部OneNote笔记 全部笔记思维导图整理 Scikit-Learn常见用法全部OneNote笔记 全部笔记思维导图整理 Java相关技术/ssm框架全部笔记 科技相关 小米手机 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 17:13:36- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |