LeetCode:503. 下一个更大元素 II - 力扣(LeetCode)
1.思路
方法一:暴力求解:两层for循环,外层遍历定位当前位置,内层遍历比较找出外层位置之后第一个较大值nums[j](这个过程循环遍历,因此用到取模操作,同时考虑不存在大于nums[i]的值,做个标记位用于结束循环)。当存在nums[j]>nums[i]时,则有ans[i] = nums[j];break;即可。 方法二:单调栈法:
2.代码实现
// 暴力解法
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] ans = new int[nums.length];
Arrays.fill(ans, -1);
for (int i = 0; i < nums.length; i++) {
// 循环判断?
int flag = 0;
for (int j = (i + 1) % nums.length; j >= 0; j = (j + 1) % nums.length) {
flag++;
if (flag > nums.length) {
break;
}
if (nums[j] > nums[i]) {
ans[i] = nums[j];
break;
}
}
}
return ans;
}
}
// 单调栈法
class Solution {
public int[] nextGreaterElements(int[] nums) {
// 下一个更大元素,则需要维持单调栈是单调递增的
int[] ans = new int[nums.length];
Arrays.fill(ans, -1);
Stack<Integer> stack = new Stack<>();
// 保证每个元素比较,需要循环遍历至少一圈
for (int i = 0; i < 2 * nums.length; i++) {
while (!stack.isEmpty() && nums[i % nums.length] > nums[stack.peek()]) {
ans[stack.peek()] = nums[i % nums.length];
stack.pop();
}
stack.push(i % nums.length);
}
return ans;
}
}
3.复杂度分析
时间复杂度:O(n ^ 2).
空间复杂度:O(n).
LeetCode:42. 接雨水 - 力扣(LeetCode)
1.思路
方法一:暴力解法,似乎也是双指针法。索引下垂直求解。以当前节点为中心,分别向两侧寻找两侧最高的柱子,木桶原理获取两者较小值与当前柱子高度的差,如果差大于0,sum+=diff。循环进行,返回结果。
方法二:单调栈法。索引下水平求解。当nums[i]<=nums[stack.peek()],直接入栈。当nums[i] >nums[stack.peek()] && !stack.isEmpty(),循环判断计算。标记栈顶mid=stack.pop(),此时的i和stack.peek()为mid的右和左的第一个较大值,高度差为diff = Math.min(nums[i],nums[stack.peek()]) - nums[i].(这个过程用到stack.peek(),因此需要判空).if(diff > 0) sum += diff * (i - stack.peek() - 1),结束while,将i加入栈。返回结果。
2.代码实现
// 暴力解法:
class Solution {
public int trap(int[] height) {
int sum = 0;
for (int i = 0; i < height.length; i++) {
if (i == 0 || i == height.length - 1) {
continue;
}
int rHeight = height[i];
int lHeight = height[i];
// 向右寻找最高的柱子
for (int j = i + 1; j < height.length; j++) {
if (height[j] > rHeight) {
rHeight = height[j];
}
}
// 向左寻找最高的柱子
for (int k = i - 1; k >= 0; k--) {
if (height[k] > lHeight) {
lHeight = height[k];
}
}
// 左右两个柱子较小的高度决定能装的雨水
int h = Math.min(lHeight, rHeight) - height[i];
if (h > 0) {
sum += h;
}
}
return sum;
}
}
// 单调栈
class Solution {
public int trap(int[] height) {
int sum = 0;
Stack<Integer> stack = new Stack<>();
stack.push(0);
for (int i = 1; i < height.length; i++) {
if (height[i] <= height[stack.peek()]) {
stack.push(i);
} else if (height[i] > height[stack.peek()]){
while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
int mid = stack.pop();
if (!stack.isEmpty()) {
int diff = Math.min(height[i], height[stack.peek()]) - height[mid];
if (diff > 0) {
sum += diff * (i - stack.peek() - 1);
}
}
}
stack.push(i);
}
}
return sum;
}
}
3.复杂度分析
时间复杂度:O(n^2).
空间复杂度:O(n).