lc352 Data Stream as Disjoint Intervals

可以用treemap解

key保存interval的start,value保存interval的end。分别找出当前val的lowerKey(treemap中>val的最小key值,没有就返回null)和higherKey(<val的最大key没有就返回null) 有以下几种情况: 1) 当前插入的key与前后两个interval重叠 合并三者,将前一个的interval.end改成后一个的end,并且将后一个从treemap中删除 2) 当前插入的key与前面的interval重叠 合并,前一个interval的end改成Math.max(end, val) 注意这里的判断条件不能写成 treemap.(treemap.lowerKey(val)) == val – 1; 而是应该写成>=,前者会出现异常,举例来说[4, 9] 现在val=7,按前者的判断条件,可能就直接放到case4里了,变成[4, 9]和[7, 7]共存 3) 当前插入的key与后面的interval重叠 put(val, 后一个的end) remove(后一个的key) 4) 当前插入的key不和任何已存在interval重叠,直接插入,按题意value设为key值

class SummaryRanges {
TreeMap<Integer, Integer> tree;
/** Initialize your data structure here. */
public SummaryRanges() {
tree = new TreeMap<>();
} public void addNum(int val) {
if(tree.containsKey(val))
return;
Integer l = tree.lowerKey(val);
Integer h = tree.higherKey(val);
Integer lv = l == null ? null : tree.get(l);
Integer hv = h == null ? null : tree.get(h); if(l != null && h != null && lv == val - 1 && h == val + 1){
//lv = hv;
tree.put(l, hv);
tree.remove(h);
}else if(l != null && lv >= val - 1){
//lv = val;
tree.put(l, Math.max(lv, val));
}else if(h != null && h == val + 1){
tree.put(val, hv);
tree.remove(h);
}else{
tree.putIfAbsent(val, val);
} } public int[][] getIntervals() {
Iterator it = tree.keySet().iterator();
int i = 0;
int[][] res = new int[tree.size()][2];
while(it.hasNext()){
Integer key = (Integer)it.next();
res[i][0] = key;
res[i][1] = tree.get(key);
i++;
}
return res;
}
/*public int[][] getIntervals() {
return tree.entrySet()
.stream()
.map(e -> new int[]{e.getKey(), e.getValue()})
.toArray(int[][]::new);
}*/
} /**
* Your SummaryRanges object will be instantiated and called as such:
* SummaryRanges obj = new SummaryRanges();
* obj.addNum(val);
* int[][] param_2 = obj.getIntervals();
*/

239 Sliding Window Maximum

1) 双向队列,时间复杂度o(n)

  a) 维护一个最大长为k(可能实际长度小于k,见b)的双向队列,保证当前队列有序,头元素为最大,这样每次只需要取dq.peek()即可。 怎么保证队列有序其头元素最大呢?每次i迭代后,把队列中没有用的元素剔除。就是把<nums[i]的元素全部剔除,然后把nums[i]的索引i放入队列。 怎么剔除?这里就用到了双向队列,从队尾开始删pollLast() 注意,队列中存放的是index而非值本身,目的是为了下一步b中确定队头元素的位置是否还在window内

  b) 保证队头的元素都来自i-k+1~i,因为这是一个sliding window。 if(dp.peek() < i-k+1) dp.poll() //直接删除队首元素

 class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums == null ||nums.length == 0)
return nums;
int len = nums.length;
int size = len - k + 1; int[] res = new int[size];
Deque<Integer> dq = new ArrayDeque<>(); for(int i=0, j=0; i<len; i++){
while(!dq.isEmpty() && dq.peek() < i - k + 1)
dq.poll(); while(!dq.isEmpty() && nums[dq.peekLast()] <= nums[i])
dq.pollLast();
dq.offer(i);
if(i >= k-1)
res[j++] = nums[dq.peek()];
} return res; }
}

2) 最大堆,时间复杂度o(nlogk)

维护一个大小为k的最大堆,可以把priorityqueue翻转一下即可 PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder()) 每次i迭代,去掉nums[i-k],插入nums[i],然后取堆root元素即可。

295 Find Median from Data Stream

用一个最大堆和一个最小堆,最大堆里放历史数据流中前k小的数,最小堆中放剩下的数,数据流总size为偶数,则两个堆大小相等,若为奇数,则最大堆比最小堆多一个数。这样我们median要么是最大堆root值,要么是两个堆root的平均值。

 class MedianFinder {
PriorityQueue<Integer> min = new PriorityQueue<>();
PriorityQueue<Integer> max = new PriorityQueue<>(Comparator.reverseOrder());
/** initialize your data structure here. */
public MedianFinder() { } public void addNum(int num) {
max.offer(num);
min.offer(max.poll());
if(max.size() < min.size())
max.offer(min.poll());
} public double findMedian() {
if(max.size() == min.size())
//return (max.poll() + min.poll()) / 2;
//poll() will remove the first element of priorityqueue, but peek() will just retrieve the value and will not remove the element
return (max.peek() +min.peek()) / 2.0;
else
return max.peek();
}
} /**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/

53 Maximum Subarray

用dp解

dp[i]定义为包含当前i的最大子序列

递归式:dp[i] = max(dp[i-1], dp[i-1] + nums[i]);

注意还要用一个max变量保存dp[i]中(i=0~n-1)最大的那个dp[i]

返回值为max

 class Solution {
public int maxSubArray(int[] nums) {
if(nums == null ||nums.length == 0)
return 0;
int len = nums.length;
int[] dp = new int[len];
dp[0] = nums[0];
int max = dp[0]; for(int i=1; i<len; i++){
dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
max = Math.max(max, dp[i]);
}
//max = Math.max(max, dp[0]);
return max;
}
}

209 Minimum Size Subarray Sum

双指针,

一个指针用来求和,即j-i的所有元素只和,sum += nums[i++]

一个指针用来减去0-j的元素, sum -= nums[j++] 每当j~i之和>=s,记录j~i的长度,用一个min记录所有ij组合的长度最小值,r然后减去当前j所指元素,j++,直到j~i之和<s

 class Solution {
public int minSubArrayLen(int s, int[] nums) {
if(nums == null || nums.length == 0)
return 0;
int i=0, j=0, min = Integer.MAX_VALUE;
int sum = 0; while(i < nums.length){
sum += nums[i++]; while(sum >= s){
min = Math.min(min, i-j);
sum -= nums[j++];
}
} return min == Integer.MAX_VALUE ? 0 : min;
} }

leetcode 352 & leetcode 239 & leetcode 295 & leetcode 53 & leetcode 209的更多相关文章

  1. Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray)

    Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray) 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. ...

  2. [LeetCode] 352. Data Stream as Disjoint Intervals 分离区间的数据流

    Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...

  3. leetcode@ [352] Data Stream as Disjoint Intervals (Binary Search & TreeSet)

    https://leetcode.com/problems/data-stream-as-disjoint-intervals/ Given a data stream input of non-ne ...

  4. Java实现 LeetCode 352 将数据流变为多个不相交区间

    352. 将数据流变为多个不相交区间 给定一个非负整数的数据流输入 a1,a2,-,an,-,将到目前为止看到的数字总结为不相交的区间列表. 例如,假设数据流中的整数为 1,3,7,2,6,-,每次的 ...

  5. leetcode 120. 三角形最小路径和 及 53. 最大子序和

    三角形最小路径和 问题描述 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...

  6. Leetcode 之Validate Binary Search Tree(53)

    判断是否是有效的二叉搜索树,即左子树的值小于根结点,右子树的值大于根结点.可以采用递归的方式来完成,递归时如何 传递有效的参数与根结点进行比较,是此题的难点. bool isValidBST(Tree ...

  7. [leetcode]352. Data Stream as Disjoint Intervals

    数据流合并成区间,每次新来一个数,表示成一个区间,然后在已经保存的区间中进行二分查找,最后结果有3种,插入头部,尾部,中间,插入头部,不管插入哪里,都判断一下左边和右边是否能和当前的数字接起来,我这样 ...

  8. 53. [LeetCode] Maximum Subarray

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  9. [leetcode] 根据String数组构造TreeNode,用于LeetCode树结构相关的测试用例

    LeetCode 跟树结构相关的题目的测试用例中大多是通过String数组来构造树.例如{2,#,3,#,4,#,5,#,6},可以构造出如下的树(将树结构逆时针选择90度显示): 6         ...

随机推荐

  1. [SNOI2017]遗失的答案

    题目 首先\(G,L\)肯定会满足\(G|L\),否则直接全部输出\(0\) 之后我们考虑一下能用到的质因数最多只有\(8\)个 同时我们能选择的数\(x\)肯定是\(L\)的约数,还得是\(G\)的 ...

  2. USACO training course Mother's Milk /// DFS(有点意思) oj10120

    题目大意: 输入 A B C 为三个容器的容量 一开始A B是空的 C是满的 每一次倾倒只能在 盛的容器满 或 倒的容器空 时才停止 输出当A容器空时 C容器内剩余量的所有可能值 Sample Inp ...

  3. Amazon AWS EC2存储

  4. minutia cylinder code MCC lSSR 匹配算法

    图一 是LSS匹配算法, 图二是LSSR 匹配算法,数据采用MCC SDK自带的十个人的数据.LSS EER6.0%左右,LSSR EER 0%

  5. MYSQL随笔心得1

    cmd链接数据库命令: 输入密码进入 显示全部的数据库: 退出服务器连接,还有/p   quit 非关系型数据库:NOSQL,not only sql 不仅仅是SQL 代表:redis,mongodb

  6. Codeforces 388D Fox and Perfect Sets

    链接:CF388D 题目大意 给定一个数\(n\),求选择\(0 \sim n\)中任意个数的数字组成的集合\(S\)中,有多少满足若\(a\in S,b\in S\),则\(a \bigoplus ...

  7. 廖雪峰Java13网络编程-2Email编程-1发送email

    1.邮件发送 1.1传统邮件发送: 传统的邮件是通过邮局投递,从一个邮局到另一个邮局,最终到达用户的邮箱. 1.2电子邮件发送: 与传统邮件类似,它是从用户电脑的邮件软件(如outlook)发送到邮件 ...

  8. com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'springCloudBus.anonymous.6Xa99MDZTJyHKdPqMyoVEA' in

    项目启动报此异常,解决方式:用root权限登陆rabbitmq,admin处添加vhost

  9. MyEclipse使用总结——MyEclipse安装maven插件[转]

    打开 myeclipse, MyEclipse -->  Preferences -->Maven4MyEclipse 确定jdk是可用的 选择自己安装的maven: 点击Add选中我们的 ...

  10. PAT甲级——A1095 Cars on Campus

    Zhejiang University has 8 campuses and a lot of gates. From each gate we can collect the in/out time ...