强化三 heap

42 Trapping Rain Water

  • two pass 从左到右 找到每个元素左边最大值; 从右到左找到每个元素右边最大值;两个最大值中小的如果比当前元素大 说明有存水 累加
  • one pass 左右相向双指针 每次小的移动 直到遇到大于当前值的 从新判断左右指针大小值

407 Trapping Rain Water II

  • 考虑到上面的思路 先把外围边界入最小堆 每次挑出堆顶并向四周延伸

295 Find Median from Data Stream
480 Sliding Window Median

  • 注意从哪一个堆里删除元素 同时删除之后为了保证minheap中元素个数等于或多一个 要调整两个堆的堆顶元素

42 Trapping Rain Water

class Solution {
    //当前高度 当前位置左边最高和右边最高的最小值
    public int trap(int[] height) {
        return onePass(height);
        // return twoPass(height);
    }
    
    public int twoPass(int[] height){
        int result = 0;
        if(height==null || height.length<=2)
            return result;
        int[] maxs = new int[height.length];
        int leftmax = -1;
        for(int i=0; i<height.length; i++){
            maxs[i] = leftmax;
            leftmax = Math.max(leftmax, height[i]);
        }
        int rightmax = -1;
        for(int i=height.length-1; i>=0; i--){
            maxs[i] = Math.min(maxs[i], rightmax);
            if(maxs[i]>height[i])
                result = result + maxs[i] - height[i];
            rightmax = Math.max(rightmax, height[i]);
        }
        return result;
    }
    
    public int onePass(int[] height) {
        if(height==null || height.length<=2)
            return 0;
        int result = 0;
        int left = 0;
        int right = height.length-1;
        while(left<right){
            int lower = Math.min(height[left],height[right]);
            if(height[left]==lower){
                left++;
                while(left<right && height[left]<=lower){
                    result = result+lower-height[left];
                    left++;
                }
            }else{
                right--;
                while(left<right && height[right]<=lower){
                    result = result+lower-height[right];
                    right--;
                }
            }
        }
        return result;
    }
}

407 Trapping Rain Water II

class Solution {
    class Cell{
        int x, y, h;
        Cell(int x, int y, int h){
            this.x = x;
            this.y = y;
            this.h = h;
        }
    }
    public int trapRainWater(int[][] heightMap) {
        int result = 0;
        if(heightMap==null || heightMap.length==0 || heightMap[0]==null || heightMap[0].length==0)
            return result;
        boolean[][] visited = new boolean[heightMap.length][heightMap[0].length];
        Comparator<Cell> com = new Comparator<Cell>(){
            public int compare(Cell a, Cell b){
                return a.h - b.h;
            }
        };
        int[] dirx = {1, -1, 0, 0};
        int[] diry = {0, 0, 1, -1};
        Queue<Cell> queue = new PriorityQueue<Cell>(com);
        init(visited, heightMap, queue);
        while(!queue.isEmpty()){
            Cell cell = queue.poll();
            for(int i=0; i<4; i++){
                int x = cell.x+dirx[i];
                int y = cell.y+diry[i];
                if(valid(x, y, visited)){
                    visited[x][y] = true;
                    queue.offer(new Cell(x, y, Math.max(heightMap[x][y], cell.h)));
                    if(cell.h>heightMap[x][y])
                        result = result + cell.h-heightMap[x][y];
                }
            }
        }
        return result;
    }
    private boolean valid(int x, int y, boolean[][] visited){
        return x>=0 && x<visited.length && y>=0 && y<visited[0].length && visited[x][y] == false;
    }
    private void init(boolean[][] visited, int[][] heightMap, Queue<Cell> queue){
        for(int i=0; i<heightMap.length; i++){
            Cell cell1 = new Cell(i, 0, heightMap[i][0]);
            visited[i][0] = true;
            Cell cell2 = new Cell(i, heightMap[0].length-1, heightMap[i][heightMap[0].length-1]);
            visited[i][heightMap[0].length-1] = true;
            queue.offer(cell1);
            queue.offer(cell2);
        }
        for(int i=0; i<heightMap[0].length; i++){
            Cell cell1 = new Cell(0, i, heightMap[0][i]);
            visited[0][i] = true;
            Cell cell2 = new Cell(heightMap.length-1, i, heightMap[heightMap.length-1][i]);
            visited[heightMap.length-1][i] = true;
            queue.offer(cell1);
            queue.offer(cell2);
        }
    }
}

295 Find Median from Data Stream

class MedianFinder {
    Queue<Integer> minHeap;
    Queue<Integer> maxHeap;
    /** initialize your data structure here. */
    public MedianFinder() {
        minHeap = new PriorityQueue<Integer>();
        maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder());
    }
    
    public void addNum(int num) {
        maxHeap.offer(num);
        minHeap.offer(maxHeap.poll());
        if(maxHeap.size()+2==minHeap.size()){
            maxHeap.offer(minHeap.poll());
        }
    }
    
    public double findMedian() {
        if(minHeap.size()==maxHeap.size()){
            return (double)(minHeap.peek()+maxHeap.peek())/2;
        }
        return minHeap.peek();
    }
}

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */

480 Sliding Window Median

class Solution {
    public double[] medianSlidingWindow(int[] nums, int k) {
        // write your code here
        if(nums==null || k<=0 || nums.length<k)
            return null;
        double[] result = new double[nums.length-k+1];
        Queue<Integer> minHeap = new PriorityQueue<Integer>();
        Queue<Integer> maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder());
        for(int i=0; i<nums.length; i++){
            maxHeap.offer(nums[i]);
            minHeap.offer(maxHeap.poll());
            if(minHeap.size()==maxHeap.size()+2)
                maxHeap.offer(minHeap.poll());
            if(i>=k-1){
                if(minHeap.size()==maxHeap.size())
                    result[i-k+1] =((double)maxHeap.peek()+ (double)minHeap.peek())/2;
                else
                    result[i-k+1] = (minHeap.peek());
                if(minHeap.peek() <= nums[i-k+1]){
                    minHeap.remove(nums[i-k+1]);
                }else{
                    maxHeap.remove(nums[i-k+1]);
                }
                if(maxHeap.size()>minHeap.size()){
                    minHeap.offer(maxHeap.poll());
                }
                if(minHeap.size()==maxHeap.size()+2)
                    maxHeap.offer(minHeap.poll());
            }
        }
        return result;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342