首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

golang刷leetcode 技巧(47)无序数组中位数

要解决这个问题首先要了解什仫中位数,所谓中位数就是一组有序数字中找到中间那个数字。...如果数字个数奇数则直接返回中间那个数,如果数字个数偶数此时这组数据中位数有两个,取中间两个数平均值即可。 想法一、不论用什仫排序算法使得该组数据有序,直接取中间值即可。...2、计算出mid所在下标,如果是奇数则是mid=(size+1)/2,如果是偶数则是mid=size/2。 3、此时需要比较mid和div所在位置。...1、如果数组元素个数奇数,取数组前(size+1)/2个元素建堆,如果是偶数则取前 size/2 个元素建堆。...3、将剩余元素全部比较完之后,此时堆顶元素就是所要求中位数。 在这里需要提到,优先级队列底层也是通过建堆来实现

98610

【面试高频题】难度 3.55,可进阶经典面试题(附进阶两问答案)

题目描述 这是 LeetCode 上「295. 数据流中位数」,难度为「困难」。 Tag : 「优先队列(堆)」 中位数有序列表中间数。如果列表长度偶数,中位数则是中间两个数平均值。...显然,为了可以 复杂度内取得当前中位数,我们应当令 l 为大根堆,r 为小根堆,并人为固定 l 和 r 之前存在如下大小关系: 当数据流元素数量偶数:l 和 r 大小相同,此时动态中位数为两者堆顶元素平均值...为了满足上述说奇偶性堆大小关系,进行 addNum 时,我们应当分情况处理: 插入前两者大小相同,说明插入前数据流元素个数为偶数插入后变为奇数。...我们期望操作完达到「l 数量为 r 多一,同时双堆维持有序」,进一步分情况讨论: 如果 r 为空,说明当前插入首个元素,直接添加到 l 即可; 如果 r 不为空,且 num <= r.peek()...插入前两者大小不同,说明前数据流元素个数为奇数插入后变为偶数

47620
您找到你想要的搜索结果了吗?
是的
没有找到

【刷穿 LeetCode】480. 滑动窗口中位数(困难)

题目描述 中位数有序序列最中间那个数。 如果序列长度偶数,则没有最中间数;此时中位数中间两个数平均数。...但这里我们求第 k 小数,而且需要两个值。还能不能使用优先队列来做呢?...开始滑动窗口,每次滑动都有一个待添加和待移除数: 2.1 根据与右堆堆顶元素比较,决定是插入哪个堆和从哪个堆移除 2.2 之后调整两堆大小(确保只会出现 left.size() == right.size...() 或 right.size() - left.size() == 1,对应了窗口长度为偶数或者奇数情况) 2.3 根据 left 堆 和 right 堆得到当前滑动窗口中位值 代码: class...nums.length; int cnt = n - k + 1; double[] ans = new double[cnt]; // 如果是奇数滑动窗口

39040

剑指Offer-数据流中中位数

题目描述 如何得到一个数据流中中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数平均值。...思路 思路一: 维护一个数组,每次加入后,进行排序,当总元素个数为奇数时,中位数就是数组中间元素;当总元素个数为偶数时,中位数就是数组中间元素和前一个元素平均数。...思路二: 维护一个大顶堆,一个小顶堆,且保证两点: 小顶堆里元素全大于大顶堆里元素; 两个堆个数差值小于等于1; 当insert数字个数为奇数时:使小顶堆个数比大顶堆多1;当insert数字个数为偶数时...如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间数值。 * 如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数平均值。...if (N % 2 == 0) { // N 为偶数情况下插入到小顶堆。

67140

数据结构链表结构

如果此数据没有缓存链表中,又可以分为两种情况:undefined如果此时缓存未满,则将此结点直接插入到链表头部;undefined如果此时缓存已满,则链表尾结点删除,将新数据结点插入链表头部。...或者 思路二 /** * 如果不存在 * 队列未满则插入 tail * 队列已满移除head并从插入 tail * 如果存在...* 队列未满则插入 tail * 队列已满移除head并从插入 tail * 如果存在 则从中取出并从插入 tail...如果是奇数个则中分开。 如果是偶数个,则认为中点有两个,继续分开。 然后分别拿到两端 head 指针就行循环,如果遇到节点数据不一致则认定不是回文串。若循环结束则认为该串回文串。...代码片段 // 判断是否为回文 public boolean palindrome() { // 根据快慢指针找到中间节点, 但是不知道总结点个数奇还是偶数

61200

数据结构-链表

如果此数据没有缓存链表中,又可以分为两种情况:undefined如果此时缓存未满,则将此结点直接插入到链表头部;undefined如果此时缓存已满,则链表尾结点删除,将新数据结点插入链表头部。...或者 思路二 /** * 如果不存在 * 队列未满则插入 tail * 队列已满移除head并从插入 tail * 如果存在...* 队列未满则插入 tail * 队列已满移除head并从插入 tail * 如果存在 则从中取出并从插入 tail...如果是奇数个则中分开。 如果是偶数个,则认为中点有两个,继续分开。 然后分别拿到两端 head 指针就行循环,如果遇到节点数据不一致则认定不是回文串。若循环结束则认为该串回文串。...代码片段 // 判断是否为回文 public boolean palindrome() { // 根据快慢指针找到中间节点, 但是不知道总结点个数奇还是偶数

38510

数据结构-链表

如果此数据没有缓存链表中,又可以分为两种情况: 如果此时缓存未满,则将此结点直接插入到链表头部; 如果此时缓存已满,则链表尾结点删除,将新数据结点插入链表头部。...或者 思路二 /** * 如果不存在 * 队列未满则插入 tail * 队列已满移除head并从插入 tail * 如果存在...* 队列未满则插入 tail * 队列已满移除head并从插入 tail * 如果存在 则从中取出并从插入 tail...如果是奇数个则中分开。 如果是偶数个,则认为中点有两个,继续分开。 然后分别拿到两端 head 指针就行循环,如果遇到节点数据不一致则认定不是回文串。若循环结束则认为该串回文串。...代码片段 // 判断是否为回文 public boolean palindrome() { // 根据快慢指针找到中间节点, 但是不知道总结点个数奇还是偶数

31010

【未完成】7-14 特殊队列 (30 分)

两种操作,分别表示队尾增加元素和取出队首元素。...现在给队列增加一种新操作 DeleteMid,表示删除队列中间元素。...对于有 N 个元素队列,若 N 为偶数中间元素定义为从队首到队尾第 N/2 个元素;若 N 为奇数中间元素定义为第 (N+1)/2 个元素。现给出队列一系列操作,输出相应结果。...之后 M 行,每行给出一条指令,为下列3种指令之一: EnQueue elem DeQueue DeleteMid 输出格式: 对于每个 EnQueue 指令,若未超出队列容量,不输出任何信息,否则在一行中输出...最后一行中按从队首到队尾顺序依次输出队列元素,以空格分隔。行尾不得有多余空格。

44020

啊这,一道找中位数算法题把东哥整不会了…

如果输入一个数组,让你求中位数,这个好办,排个序,如果数组长度奇数,最中间一个元素就是中位数,如果数组长度偶数,最中间两个元素平均数作为中位数。...PS:如果让你实现一个二叉搜索树中通过排名计算对应元素方法rank(int index),你会怎么设计?你可以思考一下,我会把答案写在留言区置顶。...好像也不太行,因为优先级队列一种受限数据结构,只能从堆顶添加/删除元素,我们addNum方法可以从堆顶插入元素,但是findMedian函数需要从数据中间取,这个功能优先级队列没办法提供。...因为我们要求中位数嘛,假设元素总数n,如果n偶数,我们希望两个堆元素个数一样,这样把两个堆堆顶元素拿出来求个平均数就是中位数;如果n奇数,那么我们希望两个堆元素个数分别是n/2 + 1和...为什么呢,稍加思考可以想明白,假设我们准备向large中插入元素如果插入num小于small堆顶元素,那么num就会留在small堆里,为了保证两个堆元素数量之差不大于 1,作为交换,把small

94310

数据流中中位数,确实轻敌了

今天刷题时候,遇到一个hard问题,也是挺有意思,剑指offer第41题和力扣【数据流中中位数】。 题目描述这样: 中位数有序列表中间数。...如果列表长度偶数,中位数则是中间两个数平均值。...所以能不能复用上次已经排好序结果? 这不就插入排序嘛! 每次新来元素相当于插入排序最后一步使他有序,然后插入…… ?...但是具体实现过程中,也有很多需要注意地方,再添加时候要先判断和其中一个堆顶比较大小,应该加到哪一个堆(优先队列)中,但是添加之后可能数值一直递增很大或者数值一直递减很小可能造成两个堆元素数量不平衡,...这里我实现时候约束小根堆元素个数等于大根堆个数(偶数)或者等于大根堆个数加一(奇数),奇数情况就直接取小根堆顶返回即可。

52960

剑指Offer题解 - Day38

数据流中中位数」 力扣题目链接[1] 如何得到一个数据流中中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间数值。...如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数平均值。...两个堆各保存一半元素,同时规定: 小顶堆保存较大一半,长度N / 2 (N偶数)或者 (N + 1) / 2 (N奇数) 大顶堆保存较小一半,长度N / 2 (N偶数)或者 (N - 1)...中位数就可以通过堆顶元素计算得到。 当添加元素时候,也就是调用addNum时候,需要做如下处理: 当N为偶数时,也就意味着大顶堆和小顶堆元素数量相等。此时需要在小顶堆中添加一个元素。...然后findMedian逻辑。需要做如下处理: 当N为偶数时,中位数(大顶堆堆顶元素 + 小顶堆堆顶元素) / 2。 当N为奇数时,中位数小顶堆堆顶元素。 上面整个流程代码逻辑。

19020

剑指offer_12_数据流中中位数

题目:数据流中中位数 描述:如果数据流中读出奇数个值,那么中位数就是数值排序之后位于中间数值,如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数平均值。...代码如下: // 优先队列默认小顶堆 staticPriorityQueue minHeap = new PriorityQueue(); // 重写比较器让他变成大顶堆 staticPriorityQueue...count = 0; public static void add(Integer number) { if (count % 2 == 0) { // 为了使小顶堆里数据都比大顶堆数据大...每次插入都要进行操作 minHeap.add(number); // 加入元素为基数时大顶堆 要多一个元素 根就是中位数了 maxHeap.add(minHeap.poll...{ return (minHeap.peek() +maxHeap.peek()) / 2.0; } else { // 为计数时大顶堆根就是中位数 因为大顶堆多一个元素

23020

【剑指Offer】41.1 数据流中中位数

NowCoder 题目描述 如何得到一个数据流中中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间数值。...如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数平均值。...(); /* 当前数据流读入元素个数 */ private int N = 0; public void Insert(Integer val) { /* 插入要保证两个堆存于平衡状态...*/ if (N % 2 == 0) { /* N 为偶数情况下插入到右半边。...* 因为右半边元素都要大于左半边,但是新插入元素不一定比左半边元素大, * 因此需要先将元素插入左半边,然后利用左半边为大顶堆特点,取出堆顶元素即为最大元素,此时插入右半边 *

27120

每日算法刷题Day15-0到n-1中缺失数字、调整数组顺序、从尾到头打印链表、用两个栈实现队列

数据范围 1≤n≤1000 样例 输入:[0,1,2,4] 输出:3 思路 此题思路比较简单,主要考察对于STL应用 本次采用思路:采用哈希表,先插入0~n-1这n个数字,然后再删除其中nums...使得所有的奇数位于数组前半部分,所有的偶数位于数组后半部分。 数据范围 数组长度 [0,100]。...判断第一个指针,如果是奇数就跳过,直到停到偶数为止 判断第二个指针,如果是偶数就跳过,直到奇数为止。 最后交换两个数即可。 当i > j时退出循环。...; 输入数据保证合法,例如,队列为空时,不会进行pop或者peek等操作; 数据范围 每组数据操作命令数量 [0,100]。...,如果想要通过两个栈实现队列操作,即先进后出。

73710

数据流中中位数

题目描述 如何得到一个数据流中中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数平均值。...setN(int n) { N = n; } /* 当前数据流读入元素个数 */ private int N = 0; public void insert...(Integer val) { /* 插入要保证两个堆存于平衡状态 */ if (N % 2 == 0) { /* N 为偶数情况下插入到右半边...* 因为右半边元素都要大于左半边,但是新插入元素不一定比左半边元素大, * 因此需要先将元素插入左半边,然后利用左半边为大顶堆特点,取出堆顶元素即为最大元素,此时插入右半边...left.add(right.poll()); } N++; } public Double getMedian() { if (N % 2 == 0)

35110

前端学数据结构与算法(十一):看似简单又让人抓狂二分查找算法

查找第一个匹配元素 这个查找规则是建立已经找到了匹配元素之后,因为找到第一个,所以首先是判断这个元素是不是数组第一个元素,然后已经找到元素上一个元素不匹配才行。...如果是使用暴力解法,那这道中等题目就太简单了,最后注意里面有强调,要保证这个解法O(logn)级别。...经过观察,这数组有个特征,长度奇数,因为只有一个数出现一次,其他数都出现两次。还有就是即使都是奇数如果中间下标均分,它又分为两种情况: 1....] 2.1 - 中间元素与前一个元素相同时,唯一不同那个元素左侧部分,因为既然都是偶数,哪边有相同元素,哪边就是奇数数组了,下一次查找截止位置为mid - 2。...如果是无序呢?那就和最后一个题目一样,排序之后再找即可。

43130

剑指offer java版(一)

例如,当字符串为We Are Happy.则经过替换之后字符串为We%20Are%20Happy。...队列元素为int类型。 解题思路 两个栈 stack1 和 stack2: push 动作都在 stack1 中进行, pop 动作 stack2 中进行。...NOTE:给出所有元素都大于0,若数组大小为0,请返回0 解题思路 类似于二分查找,定义左右两个指针left,right,计算中间指针位置mid 1、如果中间值>右边值,说明最小值右半部分,left...右移到mid+1 2、如果中间值=右边值,right左移一位,缩小距离 3、如果中间值<有右边值,说明最小值左半部分,right更新为mid public int search(int[] nums...问题描述 输入一个整数数组,实现一个函数来调整该数组中数字顺序,使得所有的奇数位于数组前半部分,所有的偶数位于位于数组后半部分,并保证奇数奇数偶数偶数之间相对位置不变。

68930

剑指Offer(六十三)-- 数据流中中位数

如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数平均值。...思路以及解答 用一个数字来不断统计数据流中个数,并且创建一个最大堆,一个最小堆,如果插入数字个数奇数时候,让最小堆里面的元素个数比最大堆个数多1,这样一来中位数就是小顶堆堆顶,如果插入数字个数偶数时候...,两个堆元素保持一样多,中位数就是两个堆堆顶元素相加除以2。...public void Insert(Integer num) { count++; if (count % 2 == 1) { // 奇数时候...,需要最小堆元素比最大堆元素多一个。

20520

LeetCode(4-寻找两个正序数组中位数&&5-最长回文子串&&6-Z形变换)

如果组合之后长度奇数,那么中位数就应该是下图所示: 如果组合之后长度偶数,那么中位数就应该是下图所示: 所以到最后我们肯定是要分情况讨论....其次如果一点都不考虑复杂度的话,我们可以直接将两个正序序列重新组合成一个正序序列,这样我们就可以我们只需要分长度偶数还是奇数讨论即可.这个就对应我第一版代码....这个就需要我们再次分情况讨论了: 当我们字符串长度偶数时候,那么很显然中间点应该是这样: 中间点并不是指向一个元素,而是一个夹缝....但是当我们字符串长度奇数时候,那么很显然中间点应该是这样: 这时候中间指向一个元素....我们分析完上面两种情况之后,我们基本就能分析得到哪些位置可以作为中间了,就如下图所示: 可以看到除了队头以及队尾元素,其他位置都是可以作为我们中间.知道了上面这些概念之后,我们思路就已经讲解完毕了

38830
领券