题目描述
给定一个不含有重复值的数组 arr,找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i] 小的位置。返回所有位置相应的信息。
输入描述:
第一行输入一个数字 n,表示数组 arr 的长度。
以下一行输出 n个数字,表示数组的值。
输出描述:
输出n行,每行两个数字 L 和 R,如果不存在,则值为-1,下标从0开始。
示例1
输入
7
3 4 1 5 6 2 7
输出
-1 2
0 2
-1 -1
2 5
3 5
2 -1
5 -1
解法一:暴力(超时)
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine());
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
func(arr,len);
}
public static void func(int[] arr,int len){
if(arr==null||len==0){
return ;
}
if(len==1){
System.out.println("-1 -1");
return ;
}
for(int i=0;i<len;i++){
int j = i-1;
int k = i+1;
StringBuilder sb = new StringBuilder();
while(j>=0){
if(arr[j]<arr[i]){
sb.append(j+" ");
break;
}
j--;
}
if(j==-1){
sb.append(-1+" ");
}
while(k<len){
if(arr[k]<arr[i]){
sb.append(k+" ");
break;
}
k++;
}
if(k==len){
sb.append(-1);
}
System.out.println(sb.toString());
}
}
}
解法二:单调栈
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine());
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
func(arr,len);
}
public static void func(int[] arr,int len){
if(arr==null||len==0){
return ;
}
if(len==1){
System.out.println("-1 -1");
return ;
}
Stack<Integer> s = new Stack<>();
String[] result = new String[len];
for(int i=0;i<len;i++){
while(!s.isEmpty()&&arr[s.peek()]>arr[i]){
int index = s.pop();
int left = s.isEmpty()?-1:s.peek();
result[index] = left+" "+i;
}
s.push(i);
}
while(!s.isEmpty()){
int index = s.pop();
int left = s.isEmpty()?-1:s.peek();
result[index] = left+" "+(-1);
}
for(int i=0;i<len;i++){
System.out.println(result[i]);
}
}
}