单调栈
解决范围内查找左侧或者右侧最小值或者最大值的问题
/**
* 获取数组中每个元素离自己最近的最小的元素
*
* 底-->顶 是 小-->大 的结构
*
* @param arr
* @return
*/
public int[][] getNearless(int[] arr) {
int[][] res = new int[arr.length][2];
//List<Integer> 放的是位置,同样大小的值的下标压在一起
//底-->顶 是 小-->大
Stack<List<Integer>> stack = new Stack<>();
for (int i = 0; i < arr.length; i++) {
// 如果栈不为空,并且栈顶的元素比当即将想入栈的数大,
// 则当前栈顶的元素,最右侧的最小值即为当前想入栈的元素
while (!stack.isEmpty() && arr[stack.peek().get(0)] > arr[i]) {
List<Integer> popIs = stack.pop();
//取位于下面的位置列表中,最晚加入的那个
int leftlessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1);
for (Integer popi : popIs) {
res[popi][0] = leftlessIndex;
res[popi][1] = i;
}
}
//比当前数小的,或者栈为空的
if (!stack.isEmpty() && arr[stack.peek().get(0)] == arr[i]) {
stack.peek().add(i);
} else {
List<Integer> list = new ArrayList<>();
list.add(i);
stack.push(list);
}
}
//最后结束,如果栈中还有元素,则都弹出
while (!stack.isEmpty()) {
List<Integer> popIs = stack.pop();
//取位于下面的位置列表中,最迟加入的那个
int leftlessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1);
for (Integer popi : popIs) {
res[popi][0] = leftlessIndex;
res[popi][1] = -1;
}
}
return res;
}