给定一个可能含有重复值的数组 arr,找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i] 小的位置。返回所有位置相应的信息。
第一行输入一个数字 n,表示数组 arr 的长度。
以下一行输入 n 个数字,表示数组的值
输出n行,每行两个数字 L 和 R,如果不存在,则值为 -1,下标从 0 开始。
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.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.io.StreamTokenizer; import java.util.Deque; import java.util.ArrayDeque; public class Main { private static StreamTokenizer st = new StreamTokenizer( new BufferedReader(new InputStreamReader(System.in)) ); private static int nextInt() { try { st.nextToken(); return (int) st.nval; } catch (IOException e) { throw new RuntimeException(e); } } private static int[][] findNearestLessThan(int[] nums) { int n = nums.length; int[][] res = new int[n][2]; Deque<Integer> stack = new ArrayDeque<>(); for (int i = 0; i < n; ++i) { while (!stack.isEmpty() && nums[i] <= nums[stack.peek()]) { stack.pop(); } res[i][0] = stack.isEmpty() ? -1 : stack.peek(); stack.push(i); } stack.clear(); for (int i = n - 1; i >= 0; --i) { while (!stack.isEmpty() && nums[i] <= nums[stack.peek()]) { stack.pop(); } res[i][1] = stack.isEmpty() ? -1 : stack.peek(); stack.push(i); } return res; } public static void main(String[] args) { int n = nextInt(); int[] arr = new int[n]; for (int i = 0; i < n; ++i) { arr[i] = nextInt(); } int[][] res = findNearestLessThan(arr); StringBuilder sb = new StringBuilder(); for (int[] pair : res) { sb.append(pair[0] + " " + pair[1] + "\n"); } System.out.println(sb); } } // 一次遍历 import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.io.StreamTokenizer; import java.util.Deque; import java.util.ArrayDeque; public class Main { private static StreamTokenizer st = new StreamTokenizer( new BufferedReader(new InputStreamReader(System.in)) ); private static int nextInt() { try { st.nextToken(); return (int) st.nval; } catch (IOException e) { throw new RuntimeException(e); } } private static int[][] findNearestLessThan(int[] nums) { int n = nums.length; int[][] res = new int[n][2]; Deque<Integer> stack = new ArrayDeque<>(); for (int i = 0; i <= n; ++i) { while (!stack.isEmpty() && (i == n || nums[i] < nums[stack.peek()])) { res[stack.pop()][1] = i < n ? i : -1; } if (i == n) { break; } if (stack.isEmpty()) { res[i][0] = -1; } else { int peek = stack.peek(); res[i][0] = (nums[i] == nums[peek]) ? res[peek][0] : peek; } stack.push(i); } return res; } public static void main(String[] args) { int n = nextInt(); int[] arr = new int[n]; for (int i = 0; i < n; ++i) { arr[i] = nextInt(); } int[][] res = findNearestLessThan(arr); StringBuilder sb = new StringBuilder(); for (int[] pair : res) { sb.append(pair[0] + " " + pair[1] + "\n"); } System.out.println(sb); } } ================================================================ import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.io.StreamTokenizer; import java.util.Deque; import java.util.ArrayDeque; public class Main { private static StreamTokenizer st = new StreamTokenizer( new BufferedReader(new InputStreamReader(System.in)) ); private static int nextInt() { try { st.nextToken(); return (int) st.nval; } catch (IOException e) { throw new RuntimeException(e); } } private static int[][] findNearestLessThan(int[] nums) { int n = nums.length; int[][] res = new int[n][2]; Deque<Integer> stack = new ArrayDeque<>(); for (int i = 0; i < n; ++i) { res[i] = new int[] {-1, -1}; } for (int i = 0; i < n; ++i) { while (!stack.isEmpty() && nums[i] < nums[stack.peek()]) { res[stack.pop()][1] = i; } if (!stack.isEmpty()) { int peek = stack.peek(); res[i][0] = (nums[i] == nums[peek]) ? res[peek][0] : peek; } stack.push(i); } return res; } public static void main(String[] args) { int n = nextInt(); int[] arr = new int[n]; for (int i = 0; i < n; ++i) { arr[i] = nextInt(); } int[][] res = findNearestLessThan(arr); StringBuilder sb = new StringBuilder(); for (int[] pair : res) { sb.append(pair[0] + " " + pair[1] + "\n"); } System.out.println(sb); } }
public /*List<Integer[]>*/static void test(int[] arr) { int n = arr.length; int[] left = new int[n]; left[0] = 0; for (int i = 1; i < n; i++) { if (arr[left[i - 1]] > arr[i]) left[i] = i; else left[i] = left[i - 1]; } int[] right = new int[n]; right[n - 1] = n - 1; for (int i = n - 2; i >= 0; i--) { if (arr[right[i + 1]] > arr[i]) right[i] = i; else right[i] = right[i + 1]; } StringBuilder sb = new StringBuilder(); int l = -1, r = 0; if (arr[right[1]] < arr[0]) { while (++r < n && arr[r] >= arr[0]) ; } else r = -1; sb.append("-1 ").append(r).append("\n"); // System.out.println("-1 " + r); for (int i = 1; i < n - 1; i++) { if (arr[i] > arr[left[i - 1]]) { // 左边存在较小的值 if (arr[i - 1] < arr[i]) l = i - 1; else if (arr[i - 1] > arr[i]) { l = i; while (--l >= 0 && arr[l] >= arr[i]) ; } } else l = -1; if (arr[i] > arr[right[i + 1]]) { // 右边存在较小的值 r = i; while (++r < n && arr[r] >= arr[i]) ; } else r = -1; // System.out.println(l + " " + r); sb.append(l).append(" ").append(r).append("\n"); // res.add(new Integer[]{l, r}); } l = n - 1; if (arr[left[n-2]] < arr[n - 1]) { while (--l < n && arr[l] >= arr[n - 1]) ; } else l = -1; sb.append(l).append(" -1\n"); System.out.println(sb); } public static void main(String[] args) { Scanner s = new Scanner(System.in); int n = Integer.parseInt(s.nextLine().trim()); int[] arr = new int[n]; String[] strings = s.nextLine().trim().split(" "); for (int i = 0;i<n;i++){ arr[i] = Integer.parseInt(strings[i]); } Main.tets(arr); }中心拓展
import java.io.*; import java.util.Arrays; import java.util.Stack; public class Main { public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); int n = Integer.parseInt(reader.readLine()); int[] arr = Arrays.stream(reader.readLine().split(" ")).mapToInt(Integer::parseInt).toArray(); int[] left = new int[n]; int[] right = new int[n]; /** * 单调递增栈 */ Stack<Integer> stack = new Stack<>(); for (int i = 0; i < arr.length; i++) { while (!stack.isEmpty() && arr[stack.peek()] > arr[i]) { right[stack.pop()] = i; } left[i] = stack.isEmpty() ? -1 : (arr[stack.peek()] == arr[i] ? left[stack.peek()] : stack.peek()); stack.push(i); } while (!stack.isEmpty()) { right[stack.pop()] = -1; } for (int i = 0; i < n; ++i) { writer.write(left[i] + " " + right[i]); writer.newLine(); } writer.flush(); } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.Stack; public class Main { public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); int N = Integer.parseInt(reader.readLine()); int[] arr = new int[N]; String[] s = reader.readLine().split(" "); reader.close(); for (int i = 0; i < arr.length; i++) { arr[i] = Integer.parseInt(s[i]); } int[][] res = new int[arr.length][2]; 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> popIndexs = stack.pop(); int leftLessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1); for (Integer popIndex : popIndexs) { res[popIndex][0] = leftLessIndex; res[popIndex][1] = i; } } if (!stack.isEmpty() && arr[stack.peek().get(0)] == arr[i]) { stack.peek().add(i); } else { ArrayList<Integer> list = new ArrayList<>(); list.add(i); stack.push(list); } } while (!stack.isEmpty()) { List<Integer> popIndexs = stack.pop(); int leftLessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1); for (Integer popIndex : popIndexs) { res[popIndex][0] = leftLessIndex; res[popIndex][1] = -1; } } StringBuilder sb = new StringBuilder(); for (int i = 0; i < res.length; i++) { sb.append(res[i][0] + " " + res[i][1] + "\n"); } System.out.println(sb.toString()); } } 一定要注意IO
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int num = sc.nextInt(); int[] nums = new int[num]; for(int i = 0 ; i < num ; i++ ){ nums[i] = sc.nextInt(); } int[][] res = solution(nums); for(int i = 0 ; i < res.length; i ++ ){ for(int j = 0 ; j < res[0].length ; j++ ){ System.out.print(res[i][j]); System.out.print(" "); } System.out.println(); } } public static int[][] solution(int[] heights) { int len = heights.length; int[][] res = new int[len][2]; Stack<Integer> mono_stack = new Stack<Integer>(); for (int i = 0; i < len; ++i) { while (!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]) { int index = mono_stack.pop(); int indexLess = mono_stack.isEmpty()?-1:mono_stack.peek(); res[index][0] = indexLess; res[index][1] = i; } mono_stack.push(i); } while(!mono_stack.isEmpty()){ int index = mono_stack.pop(); int indexLess = mono_stack.isEmpty()?-1:mono_stack.peek(); res[index][0] = indexLess; res[index][1] = -1; } return res; } 3 /// 为啥一直内存不够啊 }
import java.io.*; import java.util.*; public class Main { public static int n; public static int[] arr; public static BufferedReader buf; public static int[] left; public static int[] right; public static void process() { //第一个数的左边不存在比它小的 left[0] = -1; right[arr.length - 1] = -1; //求左边比它小的 for (int i = 1; i < arr.length; i++) { int temp = i - 1; //利用之前的left数组信息 while (temp >= 0 && arr[temp] >= arr[i]) { temp = left[temp]; } left[i] = temp; } //求右边比它小的 for (int i = arr.length - 2; i >= 0; i--) { int temp = i + 1; while (temp >= 0 && arr[temp] >= arr[i]) { temp = right[temp]; } right[i] = temp; } } public static void main(String[] args) throws IOException { buf = new BufferedReader(new InputStreamReader(System.in)); String[] strs; n = Integer.parseInt(buf.readLine()); arr = new int[n]; left = new int[n]; right = new int[n]; strs = buf.readLine().split(" "); for (int i = 0; i < n; i++) { arr[i] = Integer.parseInt(strs[i]); } process(); for (int i = 0; i < n; i++) { System.out.println(left[i] + " " + right[i]); } } }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int[] arr=new int[n]; int[][] res=new int[n][2]; Deque<Integer> stack=new ArrayDeque<>(); for(int i=0;i<n;i++){ int tmp=sc.nextInt(); arr[i]=tmp; while(!stack.isEmpty()&&arr[stack.peek()]>=tmp){ stack.pop(); } if(stack.isEmpty()) res[i][0]=-1; else res[i][0]=stack.peek(); stack.push(i); } stack.clear(); for(int i=arr.length-1;i>=0;i--){ while(!stack.isEmpty()&&arr[stack.peek()]>=arr[i]){ stack.pop(); } if(stack.isEmpty()) res[i][1]=-1; else res[i][1]=stack.peek(); stack.push(i); } StringBuilder sb=new StringBuilder(); for(int[] t:res){ sb.append(t[0]).append(" ").append(t[1]).append("\n"); } System.out.println(sb.toString()); sc.close(); } }
import java.util.Arrays; import java.util.Scanner; /** * @ Created with IntelliJ IDEA. * @ClassName Test1 * @Description 输出n行,每行两个数字 L 和 R,如果不存在,则值为 -1,下标从 0 开始 * @Author by小房 * @Date 2020/7/25 12:51 */ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int N = scanner.nextInt(); int[] array = new int[N]; for (int i = 0; i < N; i++) { array[i] = scanner.nextInt(); } for (int i = 0; i < N ; i++) { toFind(array, array[i], i); } } private static void toFind(int[] array, int num, int i) { int left = -1; int right = -1; for (int j = i; j >= 0 ; j--) { if (array[j] < num) { left = j; break; } } for (int j = i+1; j < array.length ; j++) { if (array[j] < num) { right = j; break; } } System.out.println(left + " " + right); } }
import java.util.Arrays; import java.util.Scanner; import java.util.Stack; /** * 给定一个可能含有重复值的数组 arr, * 找到每一个 i 位置左边和右边离 i 位置最近且值比 arr[i] 小的位置。返回所有位置相应的信息。 * @author zhuqiu * @date 2020/3/25 */ public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int len = in.nextInt(); int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = in.nextInt(); } int[] left = new int[len]; int[] right = new int[len]; Arrays.fill(right, -1); Arrays.fill(left, -1); method(len, left, right, arr); for (int i = 0; i < len; i++) { System.out.printf("%d %d\n", left[i], right[i]); } } public static void method(int len, int[] left, int[] right, int[] arr){ Stack<Integer> stack = new Stack(); for (int i = 0; i < len; i++) { while (!stack.isEmpty() && arr[stack.peek()] > arr[i]){ right[stack.pop()] = i; } int top = stack.isEmpty()?-1:stack.peek(); if (stack.isEmpty()){ } else if (arr[stack.peek()] != arr[i]){ left[i] = top; } else{ left[i] = left[top]; } stack.push(i); } } }只有75%,也不知道怎么优化了
import java.util.*; public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] arr = new int[n]; for(int i=0;i<n;i++) { arr[i] = sc.nextInt(); } int l,r; StringBuffer sb = new StringBuffer(); for(int i=0;i<n;i++) { l = -1; r = -1; for(int j = i-1;j>-1;j--) { if(arr[j]<arr[i]) { l = j; break; } } for(int j = i+1;j<n;j++) { if(arr[j]<arr[i]) { r = j; break; } } sb.append(l+" "+r+"\n"); } System.out.print(sb.toString()); } }