[抄题]:

给定一个包含 n 个整数的数组,和一个大小为 k 的滑动窗口,从左到右在数组中滑动这个窗口,找到数组中每个窗口内的中位数。(如果数组个数是偶数,则在该窗口排序数字后,返回第 N/2 个数字。)

对于数组 [1,2,7,8,5], 滑动大小 k = 3 的窗口时,返回 [2,7,7]

最初,窗口的数组是这样的:

[ | 1,2,7 | ,8,5] , 返回中位数 2;

接着,窗口继续向前滑动一次。

[1, | 2,7,8 | ,5], 返回中位数 7;

接着,窗口继续向前滑动一次。

[1,2, | 7,8,5 | ], 返回中位数 7;

[暴力解法]:

时间分析:

空间分析:

[思维问题]:

  1. 不理解两个heap和窗口的大小关系:把窗口容量全扔进来,具体分到哪个格子另当别论
  2. 体会到了treemap相对于heap的优越性:想romove哪个点是随便的。注意接口、实现都不是PQ,是treeset 而且树状的题想想里面装的是node还是数字

[一句话思路]:

窗口移动就是加一个元素、减一个元素,用俩函数实现,所以可以放在maxheap minheap中

[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

[画图]:

[一刷]:

  1. 窗口满了之后romove第一个点,i - k + 1,不是第i个点,写习惯了就错了。重要的参数要提前注释行
  2. 要在maxheap有点的前提下进行节点交换,想到其临界情况:还没有点

[二刷]:

[三刷]:

[四刷]:

[五刷]:

[五分钟肉眼debug的结果]:

[总结]:

参数需要边分析边写,留意leetcode lintcode接口是不是不一样

[复杂度]:Time complexity: O(n个数*左右treeset体积lgk) Space complexity: O(n)

[英文数据结构或算法,为什么不用别的数据结构或算法]:

  1. node中自己的类、自己的compareTo方法都应该有参数,否则无法调用,要理解其作用
  2. 只有implements能实现接口,还是很多个。不要写extends

[关键模板化代码]:

 自制Collections.sort 方法有一个字母 第一位不相等
 自制compareTo 方法有两个字母 第二位相等

[其他解法]:

[Follow Up]:

[LC给出的题目变变变]:

class Node implements Comparable<Node>{
int id;
int val;
Node (int id, int val){
this.id = id;
this.val = val;
}
public int compareTo(Node other) {
Node a = other;
if (this.val == a.val) {
return this.id - a.id;
}else {
return this.val - a.val;
}
}
} public class Solution {
/*
* @param nums: A list of integers
* @param k: An integer
* @return: The median of the element inside the window at each moving
*/
public double[] medianSlidingWindow(int[] nums, int k) {
//corner case
int n = nums.length;
double[] result = new double[n];
if (nums == null || k == 0) {
return result;
}
TreeSet<Node> minHeap = new TreeSet<>();
TreeSet<Node> maxHeap = new TreeSet<>();
//add all nums into window, rest
int half = (k + 1) / 2;
int index = 0;
for (int i = 0; i < k - 1; i++) {
add(minHeap, maxHeap, half, new Node(i, nums[i]));
}
for (int i = k - 1; i < n; i++) {
add(minHeap, maxHeap, half, new Node(i, nums[i]));
nums[index] = minHeap.last().val;
index++;
remove(minHeap, maxHeap, new Node(i - k + 1, nums[i - k + 1]));
} return result;
} // write reference first!
void add(TreeSet<Node> minHeap, TreeSet<Node> maxHeap, int size, Node node) {
if (minHeap.size() < size) {
minHeap.add(node);
}else {
maxHeap.add(node);
} if (minHeap.size() == size) {
//don't forget just minheap, need to ensure
if (maxHeap.size() > 0 && minHeap.last().val > maxHeap.first().val) {
Node b = minHeap.last();
Node s = maxHeap.first();
minHeap.remove(b);
minHeap.add(s);
maxHeap.remove(s);
maxHeap.add(b);
}
}
} void remove(TreeSet<Node> minHeap, TreeSet<Node> maxHeap, Node node) {
if (minHeap.contains(node)) {
minHeap.remove(node);
}else {
maxHeap.remove(node);
}
}
}

[代码风格] :

  1. 打草稿的时候先把函数参数写了 是分析出来的,不要主函数调用的时候就瞎写
  2. Node 注意开头得大写

滑动窗口的中位数 · Sliding Window Median的更多相关文章

  1. 滑动窗口协议(Sliding Window Protocol)

    滑动窗口协议(Sliding Window Protocol),属于TCP协议的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生.该协议允许发送方在停止并等待确认前发送多个数据分组.由于发送方 ...

  2. 【LeetCode】480. 滑动窗口中位数 Sliding Window Median(C++)

    作者: 负雪明烛 id: fuxuemingzhu 公众号: 每日算法题 本文关键词:LeetCode,力扣,算法,算法题,滑动窗口,中位数,multiset,刷题群 目录 题目描述 题目大意 解题方 ...

  3. 洛谷——P1886 滑动窗口|| POJ——T2823 Sliding Window

    https://www.luogu.org/problem/show?pid=1886#sub || http://poj.org/problem?id=2823 题目描述 现在有一堆数字共N个数字( ...

  4. [LeetCode] Sliding Window Median 滑动窗口中位数

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  5. Lintcode360 Sliding Window Median solution 题解

    [题目描述] Given an array of n integer, and a moving window(size k), move the window at each iteration f ...

  6. Leetcode: Sliding Window Median

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  7. Sliding Window Median LT480

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  8. LeetCode 480. Sliding Window Median

    原题链接在这里:https://leetcode.com/problems/sliding-window-median/?tab=Description 题目: Median is the middl ...

  9. 480 Sliding Window Median 滑动窗口中位数

    详见:https://leetcode.com/problems/sliding-window-median/description/ C++: class Solution { public: ve ...

随机推荐

  1. nmcli 命令的基本使用

    nmcli命令 地址配置工具:nmcli nmcli  device  查看所有网卡的信息 nmcli  device  status 和numcli device 相同 nmcli  device ...

  2. [转载]MySQL索引原理与慢查询优化

    好文,以防丢失,故转之,另对排版做简单优化.原文地址:http://ourmysql.com/archives/1401 索引目的 索引的目的在于提高查询效率,可以类比字典,如果要查"mys ...

  3. 微信应用js-sdk自定义分享图文

    之前写过步骤 但是代码很少 这里奉献上我自己写的代码 我是用js做的 先奉上js部分的代码 <head> <meta charset="utf-8"> &l ...

  4. 每天进步一点点——Linux中的线程局部存储(一)

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/26469435    在Linux系统中使用C/C++进行多线程编程时,我们遇到最多的就是对同 ...

  5. [LeetCode系列] K节点倒序问题迭代解法

    给定链表和整数k, 使用in-space方法将链表按k个为一组进行倒序, 如果剩余个数不足k个则保留其原始顺序. 如给定1->2->3->4->5, k = 2, 需要返回 2 ...

  6. Linux进程间通信——使用信号量(转)

    这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信——使用信号.下面 ...

  7. Mysql root 用户密码忘记后重置root密码

    [windows] 1.停止mysql服务:打开命令行窗口CMD,Net stop mysql 2.用另外一种方式启动Mysql:在命令行进入到mysql的安装路径下的bin目录下使用 mysqld- ...

  8. 设置JAVA HOME环境变量的秕处理

    echo "放在JDK目录下,win xp需要下载SETX.EXE" setx /m Java_Home "%cd%" setx /m ClassPath &q ...

  9. Spark系列(二) Spark Shell各种操作及详细说明

    并行化scala集合(Parallelize) //加载数据1~10 val num=sc.parallelize(1 to 10) //每个数据项乘以2,注意 _*2记为一个函数(fun) val ...

  10. javascript中不存在块级作用域,所以要小心使用在块级作用域中的函数声明所带来的作用域混乱.

    在javascript中函数的作用域是一个非常重要的概念. javascript中是没有块级作用域,但是有函数作用域的概念. 我们在开发的过程中,经常会遇到这样的问题, 某个函数我暂时不需要,不想声明 ...