diff --git a/problems/0042.接雨水.md b/problems/0042.接雨水.md index 522b10f9..4383a0b8 100644 --- a/problems/0042.接雨水.md +++ b/problems/0042.接雨水.md @@ -391,6 +391,7 @@ class Solution { } } ``` + 动态规划法 ```java class Solution { @@ -418,6 +419,54 @@ class Solution { } } ``` + +单调栈法 +```java +class Solution { + public int trap(int[] height){ + int size = height.length; + + if (size <= 2) return 0; + + // in the stack, we push the index of array + // using height[] to access the real height + Stack stack = new Stack(); + stack.push(0); + + int sum = 0; + for (int index = 1; index < size; index++){ + int stackTop = stack.peek(); + if (height[index] < height[stackTop]){ + stack.push(index); + }else if (height[index] == height[stackTop]){ + // 因为相等的相邻墙,左边一个是不可能存放雨水的,所以pop左边的index, push当前的index + stack.pop(); + stack.push(index); + }else{ + //pop up all lower value + int heightAtIdx = height[index]; + while (!stack.isEmpty() && (heightAtIdx > height[stackTop])){ + int mid = stack.pop(); + + if (!stack.isEmpty()){ + int left = stack.peek(); + + int h = Math.min(height[left], height[index]) - height[mid]; + int w = index - left - 1; + int hold = h * w; + if (hold > 0) sum += hold; + stackTop = stack.peek(); + } + } + stack.push(index); + } + } + + return sum; + } +} +``` + Python: 双指针法 diff --git a/problems/0084.柱状图中最大的矩形.md b/problems/0084.柱状图中最大的矩形.md index a0f06e8f..57df4161 100644 --- a/problems/0084.柱状图中最大的矩形.md +++ b/problems/0084.柱状图中最大的矩形.md @@ -228,6 +228,50 @@ class Solution { } ``` +单调栈 +```java +class Solution { + int largestRectangleArea(int[] heights) { + Stack st = new Stack(); + + // 数组扩容,在头和尾各加入一个元素 + int [] newHeights = new int[heights.length + 2]; + newHeights[0] = 0; + newHeights[newHeights.length - 1] = 0; + for (int index = 0; index < heights.length; index++){ + newHeights[index + 1] = heights[index]; + } + + heights = newHeights; + + st.push(0); + int result = 0; + // 第一个元素已经入栈,从下表1开始 + for (int i = 1; i < heights.length; i++) { + // 注意heights[i] 是和heights[st.top()] 比较 ,st.top()是下表 + if (heights[i] > heights[st.peek()]) { + st.push(i); + } else if (heights[i] == heights[st.peek()]) { + st.pop(); // 这个可以加,可以不加,效果一样,思路不同 + st.push(i); + } else { + while (heights[i] < heights[st.peek()]) { // 注意是while + int mid = st.peek(); + st.pop(); + int left = st.peek(); + int right = i; + int w = right - left - 1; + int h = heights[mid]; + result = Math.max(result, w * h); + } + st.push(i); + } + } + return result; + } +} +``` + Python: 动态规划 diff --git a/problems/1356.根据数字二进制下1的数目排序.md b/problems/1356.根据数字二进制下1的数目排序.md index 660434a2..06c29500 100644 --- a/problems/1356.根据数字二进制下1的数目排序.md +++ b/problems/1356.根据数字二进制下1的数目排序.md @@ -123,6 +123,31 @@ public: ## Java ```java +class Solution { + private int cntInt(int val){ + int count = 0; + while(val > 0) { + val = val & (val - 1); + count ++; + } + + return count; + } + + public int[] sortByBits(int[] arr) { + return Arrays.stream(arr).boxed() + .sorted(new Comparator(){ + @Override + public int compare(Integer o1, Integer o2) { + int cnt1 = cntInt(o1); + int cnt2 = cntInt(o2); + return (cnt1 == cnt2) ? Integer.compare(o1, o2) : Integer.compare(cnt1, cnt2); + } + }) + .mapToInt(Integer::intValue) + .toArray(); + } +} ```