1、不考虑重复值
思路分析:
1、准备一个栈结构,存放的是元素的下标,里面的元素是从小到大进行排序
2、依次遍历数组
当遍历到0位置的3时候,由于栈为空,直接入栈,此时栈中有3
当遍历到1位置的4时候,由于4比3大,直接入栈,此时栈中有3、4
当遍历到2位置的2时候,由于2比4小,此时4出栈,那么4左边比它小的是3,右边比它小的是2
然后2再去和3比较大小,由于2比3小,那么3出栈,那么3左边比它小的是无,右边比它小的是2
最后2入栈,此时栈中有2
当遍历到3位置的5时候,由于5比2大,直接入栈,此时栈中有2、5
当遍历到4位置的6时候,由于6比5大,直接入栈,此时栈中有2、5、6
当遍历到5位置的0时候,由于0比6小,那么6出栈,此时6左边比其小的是5,右边比其小的是0
此时栈中有2、5,然后0再去和5比较,那么5出栈,此时5左边比其小的是2,右边比其小的是0
此时栈中有2,然后0再去和2比较,那么2出栈,此时2左边比其小的是无,右边比其小的是0
最后0入栈,此时栈中有0
当遍历到6位置的1时候,由于1比0大,直接入栈,此时栈中有0、1
最后依次出栈
1 左边比其小的是0,右边比其小的是无
0 左边比其小的是无,右边比其小的也是无
//数组没有重复值的时候,解决方案如下:
public static int[][] getNearLessNoRepeat(int[] arr) {
int[][] res = new int[arr.length][2];
//准备一个栈结构,里面元素是从小到大进行排序
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < arr.length; i++) {
//如果队列不为空,并且队列最后一个元素值大于i位置值,那么则弹出队列最后一个元素,处理数据
while (!stack.isEmpty() && arr[stack.peek()] > arr[i]) {
int popIndex = stack.pop();
int leftLessIndex = stack.isEmpty() ? -1 : stack.peek();
res[popIndex][0] = leftLessIndex;
res[popIndex][1] = i;
}
stack.push(i);
}
//走到这一步,如果队列中还有元素,那么则依次弹出,右侧比其小的元素都没有
while (!stack.isEmpty()) {
int popIndex = stack.pop();
int leftLessIndex = stack.isEmpty() ? -1 : stack.peek();
res[popIndex][0] = leftLessIndex;
res[popIndex][1] = -1;
}
return res;
}
2、考虑重复值
思路分析(上面这个图里面数据是错误的,知道大概是这个意思就行):
1、准备一个栈,里面存放的是一个数组,数组里面存放的是元素小标,也是从小到大排序
2、当遍历到0位置的3时候,由于栈为空,直接入栈
当遍历到1位置的2时候,因为2比3小,那么3出栈,此时3左边比其小的是无,右边比其小的是2
2入栈,此时栈中有2
当遍历到2位置的3时候,由于3比2大,直接入栈
当遍历到3位置的4时候,由于4比3大,直接入参
当遍历到4位置的4时候,由于4和4相等,那么3和4位置的索引直接合并到一个集合中,入栈
。。。。。。
大致思路就是这样的了
//数组有重复值的时候,解决方案如下:
public static 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++) { // i -> arr[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(Integer.valueOf(i));
} else {
ArrayList<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;
}