LintCode 364 Trapping Rain Water II


LintCode 364 Trapping Rain Water II - earthma的专栏 - 博客频道 - CSDN.NET
Given n * m non-negative integers representing an elevation map 2d where the area of each cell is 1 * 1, compute how much water it is able to trap after raining.

给出 n * m 个非负整数,代表一张X轴上每个区域为 1 * 1 的 2d 海拔图, 计算这个海拔图最多能接住多少(面积)雨水。
给出 n * m 个非负整数,代表一张X轴上每个区域为 1 * 1 的 2D 海拔图, 计算这个海拔图最多能接住多少(面积)雨水。
例如,给定一个 5*4 的矩阵:
  [12,13,0,12],
  [13,4,13,12],
  [13,8,10,12],
  [12,13,12,12],
  [13,13,13,13]
返回 14.
也就是水往地处流,因此可以通过最小堆及BFS搜索来求解该题。
首先对矩阵数据建堆,
然后从堆里面选取最小元素,进行BSF遍历,如果值相等,继续往下走,如果遇到比当前值小的,或者边境,说明该水流会流出去(遇到这种情况对遍历的数据置为-1)说明往后连通该区域的水都会流出去,如果BFS一遍发现没有到边界和遇到比起小的点,则将遍历过的点的值设为遇到的最小的点,并更新水的流量,继续进行遍历。直至所有点都为-1为止,输出结果
http://www.jianshu.com/p/540ee7ec725b
  • 维护一个最小堆,保存最外面一圈的高度,因为最矮的格子决定了水能存放多少
  • 每次取最小高度 h,与周围4个中没有被访问过的元素进行比较
    • 如果该元素的高度小于 h,则注水到其中,并将其加入到最小堆中,设置该元素被访问过
    • 如果该元素的高度大于 h,则直接将其加入到最小堆中,设置改元素被访问过
  • 创建一个cell类,封装x, y坐标以及高度h,还有定义compare规则
  • 定义一个dx = [1, -1, 0, 0]dy = [0, 0, 1, -1]用于生成坐标(x, y)上下左右的点

class Cell:
    def __init__(self, x, y, h):
        self.x, self.y, self.h = x, y, h

    def __cmp__(self, other):
        if self.h < other.h:
            return -1
        elif self.h > other.h:
            return 1
        else:
            return 0

class Solution:
    # @param heights: a matrix of integers
    # @return: an integer
    def __init__(self):
        self.dx = [1,-1,0,0]
        self.dy = [0,0,1,-1]

    def trapRainWater(self, heights):
        if len(heights) == 0:
            return 0
        q = Queue.PriorityQueue()
        n = len(heights)
        m = len(heights[0])
        visit = [[False for i in range(m)] for i in range(n)]
        for i in range(n):
            q.put(Cell(i, 0, heights[i][0]))
            q.put(Cell(i, m-1, heights[i][m-1]))
            visit[i][0] = True
            visit[i][m-1] = True

        for i in range(m):
            q.put(Cell(0, i, heights[0][i]))
            q.put(Cell(n-1, i, heights[n-1][i]))
            visit[0][i] = True
            visit[n-1][i] = True

        ans = 0
        while not q.empty():
            now = q.get()
            for i in range(4):
                nx = now.x + self.dx[i]
                ny = now.y + self.dy[i]
                if 0 <= nx and nx < n and 0 <= ny and ny < m and not visit[nx][ny]:
                    visit[nx][ny] = True
                    q.put(Cell(nx, ny, max(now.h,heights[nx][ny])))
                    ans += max(0, now.h - heights[nx][ny])

        return ans
https://lefttree.gitbooks.io/leetcode/content/dataStructure/heap/trappingWater2.html
这一题是1的follow up,将1d的问题变成了2d,通过分析,对于matrix的能够灌水的高度,取决于最外围一圈的高度中的最小值,而找到这个最小值我们可以用heap来快速得到,python的heap是用heapq这个library来实现
  1. 用heap保存最外围的点,并且快速求得最小值
  2. 用一个visited matrix保存visit过的点
每次得到最外围的最小值,然后往内灌水(四个方向)

from heapq import *
class Solution:
    # @param heights: a matrix of integers
    # @return: an integer
    def trapRainWater(self, heights):
        # write your code here
        if not heights:
            return 0

        heap = []
        rowNum = len(heights)
        colNum = len(heights[0])
        visited = [[False for a in range(colNum)] for b in range(rowNum)]
        result = 0

        #add outside into heap
        for i in range(rowNum):
            heappush(heap, (heights[i][0], i, 0))
            heappush(heap, (heights[i][colNum-1], i, colNum-1))
            visited[i][0] = True
            visited[i][colNum-1] = True

        for j in range(1, colNum):
            heappush(heap, (heights[0][j], 0, j))
            heappush(heap, (heights[rowNum-1][j], rowNum-1, j))
            visited[0][j] = True
            visited[rowNum-1][j] = True

        dx = [1, -1, 0, 0]
        dy = [0, 0, -1, 1]
        while heap:
            curr = heappop(heap)
            for x in range(4):
                nx = curr[1] + dx[x]
                ny = curr[2] + dy[x]

                if nx >= 0 and nx < rowNum and ny >= 0 and ny < colNum and not visited[nx][ny]:
                    visited[nx][ny] = True
                    heappush(heap, (max(curr[0], heights[nx][ny]), nx, ny))
                    result += max(0, curr[0] - heights[nx][ny])

        return result
从1维升级为2维,给一个matrix, 每个cell表示海报高度,求问最多能装多少水。(最外面一圈不能装水)
BFS + Heap的解法。
从最外面一圈开始,往里找。开始的时候把最外面一圈的海拔高度加入到一个minHeap,取出外面一圈海拔最低的点curr,看四周没有被visit过的点,因为是BFS并且是由内而外,所以四周没有被visit过的,只有可能是当前一层或者更内层。
如果四周其中有一个点的海报高度低于curr,说明这个点上方肯定能积水,因为curr是外层海拔最低的,其他的海拔都要比curr还高,因此不存在那种一路低下去低到另一边的情况。
如果在curr四周发现能积水的点adj,更新result的同时,把adj也offer进minHeap以便继续往内层搜索,但是加入minHeap的高度不是adj本来的高度,而是curr的高度。因为如果再往里一层还有点比adj还低,那么蓄水高度就应该是curr.height – height,而不是adj.height – height了。
下面的code记得多读甚至多写几遍,一来是因为这道题的思路不好理解,二来也该学学matrix bfs/dfs看四周时候这种比较clean的写法了,别整天写4个方向写4个递归。
  public int trapWater(int[][] matrix) {
    if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
      return 0;
    }
 
    int m = matrix.length;
    int n = matrix[0].length;
    PriorityQueue<Node> minHeap = new PriorityQueue<>(10, new Comparator<Node>() {
      public int compare(Node a, Node b) {
        return a.height - b.height;
      }
    });
 
    boolean[][] visited = new boolean[m][n];
 
    // left and right border
    for (int i = 0; i < m; i++) {
      Node a = new Node(i, 0, matrix[i][0]);
      Node b = new Node(i, n - 1, matrix[i][n - 1]);
      minHeap.offer(a);
      minHeap.offer(b);
      visited[i][0] = true;
      visited[i][n - 1] = true;
    }
 
    // top and bottom border
    for (int j = 0; j < n; j++) {
      Node a = new Node(0, j, matrix[0][j]);
      Node b = new Node(m - 1, j, matrix[m - 1][j]);
      minHeap.offer(a);
      minHeap.offer(b);
      visited[0][j] = true;
      visited[m - 1][j] = true;
    }
 
    int[] row = {-1, 1, 0, 0};
    int[] col = {0, 0, -1, 1};
    int result = 0;
    while (!minHeap.isEmpty()) {
      Node curr = minHeap.poll();
 
      for (int i = 0; i < 4; i++) {
        int newX = curr.x + row[i];
        int newY = curr.y + col[i];
        if (newX >= 0 && newX < m && newY >= 0 && newY < n && !visited[newX][newY]) {
          result += Math.max(0, curr.height - matrix[newX][newY]);
          int newHeight = Math.max(curr.height, matrix[newX][newY]);
          minHeap.offer(new Node(newX, newY, newHeight));
          visited[newX][newY] = true;
        }
      }
    }
 
    return result;
  }
Read full article from LintCode 364 Trapping Rain Water II - earthma的专栏 - 博客频道 - CSDN.NET

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts