363. Trapping Rain Water
双指针
https://www.lintcode.com/problem/trapping-rain-water/description
思路:每个点可盛的水是左右两边最大值中的最小值-当前点的值
1 public class Solution { 2 /** 3 * @param heights: a list of integers 4 * @return: a integer 5 */ 6 public int trapRainWater(int[] heights) { 7 // write your code here 8 if(heights==null || heights.length==0){ 9 return 0; 10 } 11 12 int left = 0; 13 int right = heights.length-1; 14 15 int sum = 0; 16 int maxLeft = Integer.MIN_VALUE; 17 int maxRight =Integer.MIN_VALUE; 18 while(left<right){ 19 maxLeft = Math.max(heights[left],maxLeft); 20 maxRight = Math.max(heights[right],maxRight); 21 22 if(maxRight>maxLeft){ 23 sum +=maxLeft-heights[left]; 24 left++; 25 }else{ 26 sum+=maxRight-heights[right]; 27 right--; 28 } 29 } 30 return sum; 31 } 32 }
364. Trapping Rain Water II
https://www.lintcode.com/problem/trapping-rain-water-ii/description?_from=ladder&&fromId=4
思路:heap
循环取出最小堆堆顶,若最小值周围有更小值,说明改处可积水,那么更新sum,并将该值赋值为刚取出的堆顶值,继续将周围一圈值加入堆
class Point { int x; int y; int height; public Point(int x, int y, int height) { this.x = x; this.y = y; this.height = height; } } public class Solution { /** * @param heights: a matrix of integers * @return: an integer */ int[] dx = {0, 1, 0, -1}; int[] dy = {1, 0, -1, 0}; public int trapRainWater(int[][] heights) { // write your code here if (heights == null || heights.length == 0 || heights[0].length == 0) { return 0; } int r = heights.length; int c = heights[0].length; boolean[][] visited = new boolean[r][c]; Comparator<Point> minComparator = new Comparator<Point>() { @Override public int compare(Point o1, Point o2) { return o1.height - o2.height; } }; PriorityQueue<Point> minHeap = new PriorityQueue<>(minComparator); //将周围四条边加入最小堆 for(int i=0;i<r;i++){ minHeap.add(new Point(i,0,heights[i][0])); visited[i][0] = true; minHeap.add(new Point(i, c - 1, heights[i][c - 1])); visited[i][c - 1] = true; } for (int j = 0; j < c; j++) { minHeap.add(new Point(0, j, heights[0][j])); visited[0][j] = true; minHeap.add(new Point(r - 1, j, heights[r - 1][j])); visited[r - 1][j] = true; } //循环取出最小堆堆顶,若最小值周围有更小值,说明改处可积水 //那么更新sum,并将该值赋值为刚取出的堆顶值 //继续将周围一圈值加入堆 int sum =0; while(!minHeap.isEmpty()){ Point point = minHeap.poll(); for(int i =0;i<4;i++){ int nx = point.x+dx[i]; int ny = point.y+dy[i]; if(!isValid(nx,ny,heights,visited)){ continue; } visited[nx][ny]=true; if(heights[nx][ny]<point.height){ sum+=point.height-heights[nx][ny]; heights[nx][ny]= point.height; } minHeap.add(new Point(nx,ny,heights[nx][ny])); } } return sum; } public boolean isValid(int x, int y, int[][] heights, boolean[][] visited) { if (x < 0 || x > heights.length - 1 || y < 0 || y > heights[0].length - 1) { return false; } if (visited[x][y]) { return false; } return true; } }
360. Sliding Window Median
https://www.lintcode.com/problem/sliding-window-median/description?_from=ladder&&fromId=4
思路:heap
priorityQueue remove操作是O(N) treeset是O(logN) 此题用treeset
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 = (Node)other; if(this.val == a.val){ return this.id - a.id; } 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 List<Integer> medianSlidingWindow(int[] nums, int k) { // write your code here int n = nums.length; TreeSet<Node> minheap = new TreeSet<Node>(); TreeSet<Node> maxheap = new TreeSet<Node>(); ArrayList<Integer> result = new ArrayList<Integer> (); if (k == 0) return result; int half = (k+1)/2; 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])); result.add(minheap.last().val); remove(minheap,maxheap, new Node(i-k+1, nums[i-k+1])); } return result; } 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) { if (maxheap.size()>0 && minheap.last().val>maxheap.first().val) { Node s = minheap.last(); Node b = maxheap.first(); minheap.remove(s); maxheap.remove(b); minheap.add(b); maxheap.add(s); } } } void remove(TreeSet<Node>minheap, TreeSet<Node> maxheap, Node node) { if (minheap.contains(node)) { minheap.remove(node); } else { maxheap.remove(node); } } }