题目描述
给定一个可能含有重复值的数组 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 ;
}
Stack<ArrayList<Integer>> s = new Stack<>();
String[] res = new String[len];
for(int i=0;i<len;i++){
while(!s.isEmpty()&&arr[s.peek().get(0)]>arr[i]){
ArrayList<Integer> l = s.pop();
int left = s.isEmpty()?-1:s.peek().get(s.peek().size()-1);
while(l.size()>0){
int index = l.remove(0);
res[index] = left+" "+i;
}
}
if(!s.isEmpty()&&arr[s.peek().get(0)]==arr[i]){
s.peek().add(i);
}else{
ArrayList<Integer> l = new ArrayList<>();
l.add(i);
s.push(l);
}
}
while(!s.isEmpty()){
ArrayList<Integer> l = s.pop();
int left = s.isEmpty()?-1:s.peek().get(s.peek().size()-1);
while(l.size()>0){
int index = l.remove(0);
res[index] = left+" "+(-1);
}
}
StringBuilder sb = new StringBuilder();
for(int i=0;i<len;i++){
sb.append(res[i]);
if(i!=len-1){
sb.append("\n");
}
}
System.out.println(sb.toString());
}
}
解法二:入队时填入左边
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine().trim());
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
String[] res = fun(arr,len);
StringBuilder sb = new StringBuilder();
for(int i=0;i<len;i++){
sb.append(res[i]);
if(i<len-1) {
sb.append("\n");
}
}
System.out.println(sb.toString());
}
public static String[] fun(int[] arr,int len){
String[] res = new String[len];
if(len==0) return res;
if(len==1){
res[0] = "-1 -1";
return res;
}
Stack<Integer> s = new Stack<>();
for(int i=0;i<len;i++){
while(!s.isEmpty()&&arr[s.peek()]>arr[i]){
int tmp = s.pop();
res[tmp] += " "+i;
}
if(s.isEmpty()){
res[i] = "-1";
}else if(arr[s.peek()]!=arr[i]){
res[i] = ""+s.peek();
}else{
res[i] = res[s.peek()];
}
s.push(i);
}
while(!s.isEmpty()){
int tmp = s.pop();
res[tmp] += " -1";
}
return res;
}
}