import java.util.*; /** * NC209 最短无序连续子数组 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param nums int整型一维数组 * @return int整型 */ public int findUnsortedSubarray (int[] nums) { return solution1(nums); // return solution2(nums); // return solution3(nums); // return solution4(nums); } /** * 单调栈+贪心 * @param nums * @return */ private int solution1(int[] nums){ int n = nums.length; // 方式1 Stack<Integer> leftStack = new Stack<>(); Stack<Integer> rightStack = new Stack<>(); // 方式2 // Deque<Integer> leftStack = new ArrayDeque<>(); // Deque<Integer> rightStack = new ArrayDeque<>(); // 方式3 // Deque<Integer> leftStack = new LinkedList<>(); // Deque<Integer> rightStack = new LinkedList<>(); int left = Integer.MAX_VALUE; int right = 0; for(int i=0; i<n; i++){ // 单调栈(单调增) 从左往右 while(!leftStack.isEmpty() && nums[leftStack.peek()]>nums[i]){ // 贪心 left = Math.min(left, leftStack.pop()); } leftStack.push(i); // 单调栈(单调减) 从右往左 while(!rightStack.isEmpty() && nums[rightStack.peek()]<nums[n-i-1]){ // 贪心 right = Math.max(right, rightStack.pop()); } rightStack.push(n-i-1); } return left==Integer.MAX_VALUE?0:right-left+1; } /** * 单调栈+贪心 * @param nums * @return */ private int solution2(int[] nums){ int n = nums.length; Deque<Integer> leftStack = new ArrayDeque<>(); Deque<Integer> rightStack = new ArrayDeque<>(); int left = Integer.MAX_VALUE; int right = 0; for(int i=0; i<n; i++){ // 单调栈(单调增) 从左往右 while(!leftStack.isEmpty() && nums[leftStack.peekFirst()]>nums[i]){ // 贪心 left = Math.min(left, leftStack.pollFirst()); } leftStack.offerFirst(i); // 单调栈(单调减) 从右往左 while(!rightStack.isEmpty() && nums[rightStack.peekFirst()]<nums[n-i-1]){ // 贪心 right = Math.max(right, rightStack.pollFirst()); } rightStack.offerFirst(n-i-1); } return left==Integer.MAX_VALUE?0:right-left+1; } /** * 单调栈+贪心 * @param nums * @return */ private int solution3(int[] nums){ int n = nums.length; Deque<Integer> leftStack = new LinkedList<>(); Deque<Integer> rightStack = new LinkedList<>(); int left = Integer.MAX_VALUE; int right = 0; for(int i=0; i<n; i++){ // 单调栈(单调增) 从左往右 while(!leftStack.isEmpty() && nums[leftStack.peekLast()]>nums[i]){ // 贪心 left = Math.min(left, leftStack.pollLast()); } leftStack.offerLast(i); // 单调栈(单调减) 从右往左 while(!rightStack.isEmpty() && nums[rightStack.peekLast()]<nums[n-i-1]){ // 贪心 right = Math.max(right, rightStack.pollLast()); } rightStack.offerLast(n-i-1); } return left==Integer.MAX_VALUE?0:right-left+1; } /** * 双指针+贪心 * @param nums * @return */ private int solution4(int[] nums){ int n = nums.length; int left = Integer.MAX_VALUE; int right = 0; int min = nums[n-1]; int max = nums[0]; for(int i=1; i<n; i++){ // min(nums[n-i-1,n-1]) min = Math.min(min, nums[n-i-1]); // max(nums[0,i]) max = Math.max(max, nums[i]); // 贪心 从右往左 if(nums[n-i-1] != min){ left = n-i-1; } // 贪心 从左往右 if(nums[i] != max){ right = i; } } return left==Integer.MAX_VALUE?0:right-left+1; } }