【题目】
给你一个数组,找出数组中每个数左边离它近的比它大的数和右边离它近的比它大的数
[举例]
输入 arr[]={3 4 1 5 6 2 7}
输出
-1 2
0 2
-1 -1
2 5
3 5
2 -1
5 -1
[代码]
1.O(N^2)
public static int[][] rightWay(int []arr){
//首先创建一个结果
int [][] res=new int[arr.length][2];
//然后开始遍历
for(int i=0;i<arr.length;i++){
//在这里初始化也就是为了让每一次循环都初始化一遍,并且是-1而不是0
int leftLessIndex=-1;
int rightLessIndex=-1;
//初始化为左边的数字
int cur=i-1;
while(cur>=0){
//这里是开始找左边最小的数了
if(arr[cur]<arr[i]){
//找到了就赋值,并且中断循环
leftLessIndex=cur;
break;
}
//不然就一直减
cur--;
}
//左边的找完了之后开始找右边的
cur=i+1;
while(cur<arr.length){
if(arr[cur]< arr[i]){
//如果找到了
rightLessIndex=cur;
break;
}
//不然就一直找
cur++;
}
//找到一个之后就开始对res赋值
res[i][0]=leftLessIndex;
res[i][1]=rightLessIndex;
}
return res;
}
2.O(N)的方法
//O(N)的方法太秒了,思路就是,在栈里面存递增的序列(并且存入的是位置而不是大小)大小只是用来判断的
//当出现不能满足条件的时候,就进行对应的存位置操作,也就是要被弹出去的位置是结果位置,并且栈下面那个位置是结果位置的左边(因为能放入栈
//就说明是除栈顶元素之外,最大且小于栈顶元素的值了,而右边的,就是被触发条件的那个位置
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++){
//进栈的条件是栈为空,或者当前值大于栈顶值,所以直接来判断不能进栈的情况
while(!stack.isEmpty()&&arr[i]<stack.peek()){
//就需要开始触发条件了
//先出栈,也就是记录结果的位置
int popIndex=stack.pop();
//右边的就是i,而左边的则需要判断一下,如果非空的话,就是栈顶,如果空的话就是-1
int leftIndex=stack.isEmpty()?-1:stack.peek();
res[popIndex][0]=leftIndex;
res[popIndex][1]=i;
}
//其他情况就是正常进入
stack.push(i);
}
//然后遍历完了之后,就需要对那些满足条件的开始进行判断了,需要注意的是,这时的栈,是一个从栈顶到栈顶逐渐变大的栈
//也就是栈顶的元素的右边都是-1,左边都是栈顶元素(前提是栈顶非空)
while(!stack.isEmpty()){
int popIndex=stack.pop();
//再看一下左边的
int leftIndex=stack.isEmpty()?-1:stack.peek();
//记录结果
res[popIndex][0]=leftIndex;
res[popIndex][1]=-1;
}
return res;
}