给定一个可能含有重复值的数组 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
#include<iostream> #include<stack> #include<vector> using namespace std; int main(void) { int n = 0, num; cin >> n; stack<int> stk; vector<vector<int>> ret(n); vector<int> nums(n); for(int i = 0; i < n; i++) { cin >> num; nums[i] = num; while(!stk.empty() && nums[stk.top()] >= num) stk.pop(); if(stk.empty()) ret[i] = vector<int>{-1, -1}; else ret[i] = vector<int>{stk.top(), -1}; stk.push(i); } while(!stk.empty()) { stk.pop(); } for(int i = n - 1; i >= 0; i--) { while(!stk.empty() && nums[stk.top()] >= nums[i]) stk.pop(); if(stk.empty()) ret[i][1] = -1; else ret[i][1] = stk.top(); stk.push(i); } for(int i = 0; i < n; i++) { cout << ret[i][0] << " " << ret[i][1] << endl; } }超时代码
#include<iostream> #include<stack> #include<vector> #include<cstdio> using namespace std; int main(void) { int n = 0; cin >> n; stack<int> stk; vector<vector<int> > ret(n,{-1,-1}); vector<int> nums(n); for(int i = 0; i < n; i++) { cin >> nums[i]; while(!stk.empty() && nums[stk.top()] >= nums[i]) stk.pop(); if(!stk.empty()) ret[i][0] = stk.top(); stk.push(i); } while(!stk.empty()) { stk.pop(); } for(int i = n - 1; i >= 0; i--) { while(!stk.empty() && nums[stk.top()] >= nums[i]) stk.pop(); if(!stk.empty()) ret[i][1] = stk.top(); stk.push(i); } for(int i = 0; i < n; i++) { cout <<ret[i][0] << " " << ret[i][1] << endl; } }
// // Created by yuanhao on 2019-8-30. // #include <iostream> using namespace std; // 可以用两个栈分两次做,这样只能过75%数据, // 如果用一次循环,使用stl的stack<pair<int,int>>,可以过95%, // 要想过100%,还得自己手写栈提高速度,而且不要用pair,对象多了也会耗时间。。。 // 没办法,为了考察出两倍的时间差异,这道题对时间卡得比较死 int main() { int n = 0; cin >> n; int numbers[n]; int l_res[n]; int r_res[n]; for (int i = 0; i < n; ++i) { cin >> numbers[i]; } int stack[n * 2]; // 栈,保存数字下标和数字,两个元素为一个帧 int top = 0; //栈顶指针 for (int i = 0; i < n; ++i) { while (top != 0 && numbers[i] < stack[top - 1]) { r_res[stack[top - 2]] = i; top -= 2; } if (top == 0) { l_res[i] = -1; } else { if (numbers[i] == stack[top - 1]) { l_res[i] = l_res[stack[top - 2]]; } else { l_res[i] = stack[top - 2]; } } stack[top++] = i; stack[top++] = numbers[i]; } while (top != 0) { r_res[stack[top - 2]] = -1; top -= 2; } for (int i = 0; i < n; ++i) { printf("%d %d\n", l_res[i], r_res[i]); } return 0; }
头条一面没写出来,现在运行不出来
#include (849)#include #include using namespace std; int main() { int n = 0; cin >> n; vector nums(n); for (int i = 0; i < n; i++) { cin >> nums[i]; } vector prevs(n, -1); vector nexts(n, -1); stack s; s.push(0); for (int i = 1; i < nums.size(); i++) { if (nums[s.top()] <= nums[i]) { prevs[i] = s.top(); s.push(i); } else { while (!s.empty() && nums[s.top()] > nums[i]) { s.pop(); } if (!s.empty()) { prevs[i] = s.top(); } s.push(i); } } s.push(n - 1); for (int i = n - 2; i >= 0; i--) { if (nums[i] < nums[s.top()]) { s.push(i); } else { nexts[i] = s.top(); } } for (int i = 0; i < n; i++) { cout << prevs[i] << " " << nexts[i] << endl; } }
a=input() b=[int(i) for i in input().split()] def left(c): n = c - 1 for j in reversed(b[:c]): if b[c]>j: return n n-=1 return -1 def right(c): n=c+1 for i in b[c+1:]: if b[c]>i: return n n+=1 return -1 i=0 while i<len(b): cen=b[i] if i==0: le=-1 r=right(i) print(le,r) elif i==len(b)-1: le=left(i) r=-1 print(le,r) else: le=left(i) r=right(i) print(le,r) i+=1
#include <bits/stdc++.h> using namespace std; struct node { int left, right; }; int main(int argc, char const *argv[]) { int n; cin >> n; vector<int> a; for (int i = 0; i < n; i++) { int t; cin >> t; a.push_back(t); } vector<node> nn(n); for (int i = 0; i < n; i++) { nn[i].left = -1; nn[i].right = -1; } nn[0].left = -1; for (int kk = 1; kk < a.size(); kk++) { if (a[0] > a[kk]) { nn[0].right = kk; break; } } nn[a.size() - 1].right = -1; for (int kk = a.size() - 2; kk >= 0; kk--) { if (a[a.size() - 1] > a[kk]) { nn[a.size() - 1].left = kk; break; } } for (int i = 1; i < a.size() - 1; i++) { for (int jj = i - 1; jj >= 0; jj--) /*left*/ { if (a[jj] < a[i]) { nn[i].left = jj; break; } } for (int kkk = i + 1; kkk < a.size(); kkk++)/*right*/ { if (a[i] > a[kkk]) { nn[i].right = kkk; break; } } } for (int i = 0; i < n; i++) { cout << nn[i].left << " " << nn[i].right << endl; } return 0; }75% 纯数组写的
#include <vector> #include <iostream> #include <stack> #include <stdio.h> using namespace std; int main() { int n; scanf("%d", &n); vector<int> datas(n); vector<int> Lres(n, -1); vector<int> Rres(n, -1); stack<int> arrdeq; for (int i = 0; i < n; i++) { scanf("%d", &datas[i]); while (!arrdeq.empty() && datas[arrdeq.top()] >= datas[i]) { arrdeq.pop(); } if (!arrdeq.empty()) { Lres[i] = arrdeq.top(); } arrdeq.push(i); } stack<int> arrdeq2; for (int i = n - 1; i >= 0; i--) { while (!arrdeq2.empty() && datas[arrdeq2.top()] >= datas[i]) { arrdeq2.pop(); } if (!arrdeq2.empty()) { Rres[i] = arrdeq2.top(); } arrdeq2.push(i); } for (int i = 0; i < n; i++) { printf("%d %d\n", Lres[i], Rres[i]); } return 0; }
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(); } }
#include <bits/stdc++.h> using namespace std; int main(){ int n; cin>>n; int a[n], l[n], r[n]; stack<int> S; for(int i=0;i<n;i++){ cin>>a[i]; l[i] = r[i] = -1; } for(int i=0;i<n;){ if(S.empty()){ S.push(i++); }else if(a[i]>=a[S.top()]){ if(a[i] == a[S.top()]) l[i] = l[S.top()]; else l[i] = S.top(); S.push(i++); }else{ r[S.top()] = i; S.pop(); } } for(int i=0;i<n;i++) printf("%d %d\n", l[i], r[i]); return 0; }
#include <stdio.h> #include<malloc.h> int main() { int n,*arr; scanf("%d",&n); arr=(int *)malloc(sizeof(int)*n); for(int a=0;a<n;a++) { scanf("%d",arr+a); } for(int a=0,e=0,b;a<n;a++) {e=0; for( b=a-1;b>=0;b--) { if(*(arr+b)<*(arr+a)) { printf("%d ",b); e=1; break; } } if(!e) { printf("-1 "); } e=0; for(b=a+1;b<n;b++) { if(*(arr+b)<*(arr+a)) { printf("%d",b); e=1; break; } } if(!e) { printf("-1"); } printf("\n"); }}
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.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); } }
# 用list模拟单调栈 n = int(input()) arr = [int(k) for k in input().split()] left = [-1 for _ in range(n)] stk = [] # 左向右 for i in range(n): while stk and arr[stk[-1]] >= arr[i]: stk.pop() if stk: left[i] = stk[-1] stk.append(i) right = [-1 for _ in range(n)] stk = [] # 右向左 for i in range(n-1, -1, -1): while stk and arr[stk[-1]] >= arr[i]: stk.pop() if stk: right[i] = stk[-1] stk.append(i) for i in range(n): print(f"{left[i]} {right[i]}")
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(); } }
#include <iostream> #include <vector> #include <stack> using namespace std; int main() { int size; scanf("%d", &size); vector<int> arr(size); vector<int> ans1(size,-1); vector<int> ans2(size,-1); stack<int> s; stack<int> s1; for (int i = 0; i < size; i++) { scanf("%d", &arr[i]); while (!s.empty() && arr[s.top()] >= arr[i]) { s.pop(); } if (!s.empty()) ans1[i] = s.top(); s.push(i); } for (int i = size - 1; i >= 0; i--) { while (!s1.empty() && arr[s1.top()] >= arr[i]) { s1.pop(); } if (!s1.empty()) ans2[i] = s1.top(); s1.push(i); } for (int i = 0 ; i < size; i++) { printf("%d %d\n", ans1[i], ans2[i]); } return 0; }
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 /// 为啥一直内存不够啊 }