Problem

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example,
Given[0,1,0,2,1,0,1,3,2,1,2,1], return6.

思路一(heap)

  • for ith bar, we need to find the highest bar on its left and right
  • then get MIn(left, right), and add to res
  • so use two heap, left and right
  • time complexity: O(n^2), because heap's remove operation takes O(n) time
  • space complexity: O(n)
    public int trap(int[] height) {
        if (height == null || height.length <= 2) {
            return 0;
        }
        int res = 0;
        int len = height.length;
        Bar[] bars = new Bar[len];
        for (int i = 0; i < len; i++) {
            bars[i] = new Bar(i, height[i]);
        }
        PriorityQueue<Bar> left = new PriorityQueue<>(len, (Bar b1, Bar b2) -> b2.height - b1.height);
        PriorityQueue<Bar> right = new PriorityQueue<>(len, left.comparator());

        for (int i = len - 1; i >= 2; i--) {
            right.offer(bars[i]);
        } 
        left.offer(bars[0]);
        for (int i = 1; i < len - 1; i++) {
            Bar cur = bars[i];
            // System.out.println("left : " + left.peek().height);
            // System.out.println("right : " + right.peek().height);
            if (left.peek().height > cur.height && right.peek().height > cur.height) {
                // System.out.println("hello");
                res += Math.min(left.peek().height, right.peek().height) - cur.height;
            }
            left.offer(cur);
            right.remove(bars[i + 1]);
        }
        return res;
    }

    class Bar {
        int index;
        int height;
        public Bar(int i, int h) {
            index = i;
            height = h;
        }
    }

优化(TreeSet)

  • treeset's remove takes O(logn)
  • one thing needs to be notice is that the comparator should be modified, because its equals() function depends on it. if heights are the same, the set just keeps one.
  • time complexity: O(nlogn)
    public int trap(int[] height) {
        if (height == null || height.length <= 2) {
            return 0;
        }
        int res = 0;
        int len = height.length;
        Bar[] bars = new Bar[len];
        for (int i = 0; i < len; i++) {
            bars[i] = new Bar(i, height[i]);
        }
        TreeSet<Bar> left = new TreeSet<>(new Comparator<Bar>(){
            public int compare(Bar b1, Bar b2) {
                if (b2.height - b1.height == 0) {
                    return b1.index - b2.index;
                }
                return b2.height - b1.height;
            }
        });
        TreeSet<Bar> right = new TreeSet<>(left.comparator());

        for (int i = len - 1; i >= 2; i--) {
            right.add(bars[i]);
        } 
        // System.out.println(right.size());
        left.add(bars[0]);
        for (int i = 1; i < len - 1; i++) {
            Bar cur = bars[i];

            int l = left.first().height;
            int r = right.first().height;
            if (l > cur.height && r > cur.height) {
                res += Math.min(l, r) - cur.height;
            }
            left.add(cur);
            right.remove(bars[i + 1]);
        }
        return res;
    }

    class Bar {
        int index;
        int height;
        public Bar(int i, int h) {
            index = i;
            height = h;
        }
    }

results matching ""

    No results matching ""