单调栈-四元组问题

四元组问题

问题描述

从小学开始,小明就是一个非常喜欢数学的孩子。他喜欢用数学的方式解决各种问题。在他的高中时期,他遇到了一个非常有趣的问题,那就是给定一个长度为 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();      
    }
   
}
相关推荐
huang57914722 分钟前
基于滑动窗口的流式数据算法优化思路3
算法
Ulyanov34 分钟前
AudioVision Pro:基于 PySide6 + sounddevice 的实时音频可视化播放器设计
python·算法·音视频
土司大王1 小时前
LeetCode hot100——74.搜索二维矩阵:Java 二分模板
java·算法·leetcode
tyler_download1 小时前
揉扁搓圆transformer架构:NAG优化器算法详解
深度学习·算法·transformer
weixin199701080161 小时前
[特殊字符]《京东POP二手品类对接:B2C订单模型 vs 二手C2C属性的字段转换难题》(附Python源码)
前端·python·算法
BizzZ_1 小时前
算法(1)——双指针
数据结构
Doubbbbbbble云1 小时前
内存碎片化对数据结构操作性能的影响研究4
数据结构
Jared_devin2 小时前
单头、多头 Self-Attention可视化
人工智能·pytorch·深度学习·算法·机器学习·pycharm
wuyk5552 小时前
18.Kruskal 算法:用最短的边连成一张网
开发语言·算法·图论
pen-ai3 小时前
【优化方法】最小二乘:从误差平方到线性与非线性拟合
人工智能·算法·机器学习