暴力解法:(会超时)
class Solution {
public int largestRectangleArea(int[] heights) {
if (heights == null || heights.length == 0) {
return 0;
}
int len = heights.length;
if (len == 1) {
return heights[0];
}
int res = 0;
for (int i = 0; i < len; i++) {
int l = i - 1;
while (l >= 0 && heights[l] >= heights[i]) {
l--;
}
int r = i + 1;
while (r < len && heights[r] >= heights[i]) {
r++;
}
res = Math.max(res, (r - l - 1) * heights[i]);
}
return res;
}
}
单调栈:
class Solution {
public int largestRectangleArea(int[] heights) {
if (heights == null || heights.length == 0) {
return 0;
}
int len = heights.length;
if (len == 1) {
return heights[0];
}
int res = 0;
Deque<Integer> stack = new ArrayDeque<>();
for (int i = 0; i < len; i++) {
while (!stack.isEmpty() && heights[i] < heights[stack.peekLast()]) {
int curHeight = heights[stack.pollLast()];
while (!stack.isEmpty() && heights[stack.peekLast()] == curHeight) {
stack.pollLast();
}
int curWidth;
if (stack.isEmpty()) {
curWidth = i;
} else {
curWidth = i - stack.peekLast() - 1;
}
res = Math.max(res, curHeight * curWidth);
}
stack.offerLast(i);
}
while (!stack.isEmpty()) {
int curHeight = heights[stack.pollLast()];
while (!stack.isEmpty() && heights[stack.peekLast()] == curHeight) {
stack.pollLast();
}
int curWidth;
if (stack.isEmpty()) {
curWidth = len;
} else {
curWidth = len - stack.peekLast() - 1;
}
res = Math.max(res, curHeight * curWidth);
}
return res;
}
}
加入哨兵的解法:
class Solution {
public int largestRectangleArea(int[] heights) {
if (heights == null || heights.length == 0) {
return 0;
}
int len = heights.length;
if (len == 1) {
return heights[0];
}
int res = 0;
int[] newHeights = new int[len + 2];
System.arraycopy(heights, 0, newHeights, 1, len);
newHeights[0] = newHeights[len + 1] = 0;
Deque<Integer> stack = new ArrayDeque<>();
stack.offerLast(newHeights[0]);
for (int i = 1; i < len + 2; i++) {
while (newHeights[i] < newHeights[stack.peekLast()]) {
int curHeight = newHeights[stack.pollLast()];
int curWidth = i - stack.peekLast() - 1;
res = Math.max(res, curHeight * curWidth);
}
stack.offerLast(i);
}
return res;
}
}
暴力法:
class Solution {
public int trap(int[] height) {
int res = 0;
int n = height.length;
for (int i = 1; i < n - 1; i++) {
int maxLeft = 0, maxRight = 0;
for (int j = i; j >= 0; j--) {
maxLeft = Math.max(maxLeft, height[j]);
}
for (int j = i; j < n; j++) {
maxRight = Math.max(maxRight, height[j]);
}
res += Math.min(maxLeft, maxRight) - height[i];
}
return res;
}
}
动态规划:
class Solution {
public int trap(int[] height) {
if (height == null || height.length < 3) {
return 0;
}
int n = height.length;
int[] leftMax = new int[n];
int[] rightMax = new int[n];
leftMax[0] = height[0];
for (int i = 1; i < n - 1; i++) {
leftMax[i] = Math.max(leftMax[i - 1], height[i]);
}
rightMax[n - 1] = height[n - 1];
for (int i = n - 2; i > 0; i--) {
rightMax[i] = Math.max(rightMax[i + 1], height[i]);
}
int res = 0;
for (int i = 1; i < n - 1; i++) {
res += Math.min(leftMax[i], rightMax[i]) - height[i];
}
return res;
}
}
单调栈:
class Solution {
public int trap(int[] height) {
Deque<Integer> stack = new ArrayDeque<>();
int res = 0, cur = 0;
while (cur < height.length) {
while (!stack.isEmpty() && height[cur] > height[stack.peekLast()]) {
int top = stack.pollLast();
if (stack.isEmpty()) {
break;
}
int distance = cur - stack.peekLast() - 1;
int bounded_height = Math.min(height[cur], height[stack.peekLast()]) - height[top];
res += distance * bounded_height;
}
stack.offerLast(cur++);
}
return res;
}
}
双指针:
class Solution {
public int trap(int[] height) {
int i = 0, j = height.length - 1;
int left_max = 0, right_max = 0;
int res = 0;
while (i < j) {
if (height[i] < height[j]) {
if (height[i] >= left_max) {
left_max = height[i];
} else {
res += (left_max - height[i]);
}
i++;
} else {
if (height[j] >= right_max) {
right_max = height[j];
} else {
res += (right_max - height[j]);
}
j--;
}
}
return res;
}
}
暴力法:
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] res = new int[n];
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (temperatures[j] > temperatures[i]) {
res[i] = j - i;
break;
}
}
}
return res;
}
}
单调栈:
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
Stack<Integer> stack = new Stack<>();
int n = temperatures.length;
int[] res = new int[n];
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {
int index = stack.pop();
res[index] = i - index;
}
stack.push(i);
}
return res;
}
}
暴力法:
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
int[] res = new int[len1];
Arrays.fill(res, -1);
for (int i = 0; i < len1; i++) {
for (int j = 0; j < len2; j++) {
if (nums1[i] != nums2[j]) {
continue;
}
for (int p = j + 1; p < len2; p++) {
if (nums2[p] > nums1[i]) {
res[i] = nums2[p];
break;
}
}
break;
}
}
return res;
}
}
单调栈:
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
int[] res = new int[len1];
Arrays.fill(res, -1);
int[] temp = new int[len2];
Deque<Integer> stack = new ArrayDeque<>();
for (int i = 0; i < len2; i++) {
while (!stack.isEmpty() && nums2[i] > nums2[stack.peekLast()]) {
int top = stack.pollLast();
temp[top] = i - top;
}
stack.offerLast(i);
}
for (int i = 0; i < len1; i++) {
for (int j = 0; j < len2; j++) {
if (nums1[i] != nums2[j]) {
continue;
}
if (temp[j] != 0) {
res[i] = nums2[j + temp[j]];
}
break;
}
}
return res;
}
}
改进:
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
int[] res = new int[len1];
Deque<Integer> stack = new ArrayDeque<>();
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < len2; i++) {
while (!stack.isEmpty() && nums2[i] > stack.peekLast()) {
map.put(stack.pollLast(), nums2[i]);
}
stack.offerLast(nums2[i]);
}
for (int i = 0; i < len1; i++) {
res[i] = map.getOrDefault(nums1[i], -1);
}
return res;
}
}
单调栈:
class Solution {
public String removeDuplicateLetters(String s) {
int len = s.length();
int[] lastIndex = new int[26];
char[] charArray = s.toCharArray();
for (int i = 0; i < len; i++) {
lastIndex[charArray[i] - 'a'] = i;
}
boolean[] visited = new boolean[26];
Deque<Character> stack = new ArrayDeque<>();
for (int i = 0; i < len; i++) {
if (visited[charArray[i] - 'a']) {
continue;
}
while (!stack.isEmpty() && stack.peekLast() > charArray[i] && lastIndex[stack.peekLast() - 'a'] > i) {
char top = stack.pollLast();
visited[top - 'a'] = false;
}
stack.offerLast(charArray[i]);
visited[charArray[i] - 'a'] = true;
}
StringBuilder sb = new StringBuilder();
for (char c : stack) {
sb.append(c);
}
return sb.toString();
}
}
单调栈:
class StockSpanner {
Deque<Integer> prices, weights;
public StockSpanner() {
prices = new ArrayDeque<Integer>();
weights = new ArrayDeque<Integer>();
}
public int next(int price) {
int w = 1;
while (!prices.isEmpty() && prices.peekLast() <= price) {
prices.pollLast();
w += weights.pollLast();
}
prices.offerLast(price);
weights.offerLast(w);
return w;
}
}
/**
* Your StockSpanner object will be instantiated and called as such:
* StockSpanner obj = new StockSpanner();
* int param_1 = obj.next(price);
*/
单调栈:
class Solution {
public String removeKdigits(String num, int k) {
Deque<Character> stack = new ArrayDeque<>();
int len = num.length();
if (k == len) {
return "0";
}
for (int i = 0; i < len; i++) {
char digit = num.charAt(i);
while (!stack.isEmpty() && k > 0 && stack.peekLast() > digit) {
stack.pollLast();
k--;
}
stack.offerLast(digit);
}
if (k > 0) {
for (int i = 0; i < k; i++) {
stack.pollLast();
}
}
boolean leadingZero = true;
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) {
char digit = stack.pollFirst();
if (leadingZero && digit == '0') {
continue;
}
leadingZero = false;
sb.append(digit);
}
return sb.length() == 0 ? "0" : sb.toString();
}
}
单调栈:
class Solution {
public int findUnsortedSubarray(int[] nums) {
int len = nums.length;
Deque<Integer> stack = new ArrayDeque<>();
int l = len - 1;
for (int i = 0; i < len; i++) {
while (!stack.isEmpty() && nums[stack.peekLast()] > nums[i]) {
l = Math.min(l,stack.pollLast() );
}
stack.offerLast(i);
}
int r = 0;
stack.clear();
for (int i = len - 1; i >= 0; i--) {
while (!stack.isEmpty() && nums[stack.peekLast()] < nums[i]) {
r = Math.max(r, stack.pollLast());
}
stack.offerLast(i);
}
return r > l ? r - l + 1 : 0;
}
}