单调栈-四元组问题

四元组问题

问题描述

从小学开始,小明就是一个非常喜欢数学的孩子。他喜欢用数学的方式解决各种问题。在他的高中时期,他遇到了一个非常有趣的问题,那就是给定一个长度为 nn 的整数数组 numsnums ,判断是否存在四个不同的下标 a,b,c,da,b,c,d ,使得 aa < bb < cc < dd ,并且 numsdnumsd < numscnumsc < numsanumsa < numsbnumsb

小明非常喜欢这个问题,他决定用数学的方式来解决它。他首先想到了一个非常简单的方法,那就是暴力枚举。他用四个循环来枚举所有可能的下标组合,然后判断是否满足条件。但是这个方法非常耗时,当 nn 很大时,计算量会非常大。

所以请求你给出一个快速智慧的解决办法。

输入格式

输入仅两行,第一行包含一个整数 nn ,第二行包含 nn 个整数,其含义如上所述。

输出格式

输出仅一行,包含一个字符串, YES 表示题目存在上面所描述的情况,否则输出 NO

样例输入

复制代码
4
3 4 2 1

样例输出

复制代码
YES

说明

在样例中,当 a,b,c,da,b,c,d 分别等于 0,1,2,30,1,2,3 满足 aa < bb < cc < dd ,并且使得 numsdnumsd < numscnumsc < numsanumsa < numsbnumsb

评测数据规模

对于 5050% 的评测数据, 4≤n≤200,−200≤numsi≤2004≤n≤200,−200≤numsi≤200 。

对于 100100% 的评测数据,4≤n≤5×105,−109≤numsi≤1094≤n≤5×105,−109≤numsi≤109 。

复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.*;


public class Main {

    static int N=5*100010;
    
    
    static int a[]=new int[N];
   
    static int n;
    
    
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
    
    public static void main(String[] args) throws IOException { 
        StringTokenizer st=new StringTokenizer(br.readLine());
        n=Integer.parseInt(st.nextToken());
                
        st=new StringTokenizer(br.readLine());
        for (int i = 1; i <= n; i++) {
			a[i]=Integer.parseInt(st.nextToken());
		}
        //nums[d] < nums[c] < nums[a] < nums[b]
        //对于c而言 我想知道我的右侧是否有比我小的数
        int rightMin[]=new int[n+1];//维护一个后缀最小值
        rightMin[n]=n;
        for (int i = n-1; i > 0; i--) {
		  if(a[i]<a[rightMin[i+1]]){
			  rightMin[i]=i;
		  }else{
			  rightMin[i]=rightMin[i+1];
		  }
		}
        //站在c的角度上 我迫切的想知道我的左侧是否存在两个数满足 nums[a] < nums[b]
        //如果说当前的模拟的c< 我的左侧所有数中 次大的数时 说明我找到了 nums[c] < nums[a] < nums[b] 这样一种关系
        //因为四大的数找到了,那么必然存在一个比它大的数
        //我们维护一个单调递减的栈   当栈顶的元素小于我遍历到的数时  我们就找到了一个 nums[a] < nums[b]这样的序列
        //这时我们将num[a] 也就是次大值poll并记录该值  max2 
        int max2=Integer.MIN_VALUE;;
        Deque<Integer> deque=new LinkedList<Integer>();
        boolean f=false;
        for (int i = 1; i <= n; i++) {
        	int u=a[i];
        	//将当前数作为c 看是否符合条件
        	if(u<max2 && u<rightMin[i]){
        		bw.write("YES");
        		f=true;
        		break;
        	}
        	
        	//当前的数可以用于更新max2   我们记录最大的max2 是为了使得更多的c更有可能满足条件  
        	while(!deque.isEmpty() && deque.peekLast()<u)max2=Math.max(max2, deque.pollLast());
        	deque.add(u);       	
		}
        if(!f)bw.write("NO");
        
        br.close();
        bw.flush();
        bw.close();      
    }
   
}
相关推荐
冷小鱼1 小时前
AI Agent 核心算法:任务规划(Planning)的深度技术解析
人工智能·算法·planning
退休倒计时1 小时前
【每日一题】LeetCode 78. 子集 TypeScript
算法·leetcode·typescript
旖-旎1 小时前
《LeetCode 978 最长湍流子数组 || LeetCode 139 单词拆分》
c++·算法·leetcode·动态规划
cxr8282 小时前
第16章 跨域迁移与能力融合——从专家到通才
人工智能·算法·智能体·hermes
学究天人2 小时前
数学公理体系大全:Comprehensive Collection of Mathematical Axiom Systems(补充卷9)
人工智能·线性代数·算法·数学建模·动态规划·原型模式·抽象代数
Keven_112 小时前
算法札记:图的存储方式
算法·图论
斯文的八宝粥2 小时前
SERL:让真机强化学习从“难用”走向“可复现”的强化学习框架 ----(4)算法篇(DrQ vs VICE)
算法
yangdaxiageo2 小时前
算法时代的“心智置顶“:《功夫女足》如何构建GEO正向飞轮
人工智能·科技·算法·aigc
ysa0510302 小时前
【板子】欧拉序
c++·笔记·算法·深度优先·图论