单调栈结构及其应用


下一个更大元素 I


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

class Solution {
    //单调栈+哈希
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Map<Integer,Integer>map=new HashMap<>();
        Stack<Integer>st=new Stack<>();//次单调栈维持自栈底往上单调递减
        st.push(0);
        for(int i=1;i<nums2.length;++i){
            if(nums2[i]<nums2[st.peek()]){
                st.push(i);
            }else{
                while(!st.isEmpty()&&nums2[st.peek()]<nums2[i]){
                    map.put(nums2[st.pop()],nums2[i]);
                }
                st.push(i);
            }
        }
        while(!st.isEmpty()){
            map.put(nums2[st.pop()],-1);
        }
        int[] ans=new int[nums1.length];
        for(int i=0;i<nums1.length;++i){
            ans[i]=map.get(nums1[i]);
        }
        return ans;
    }
}

在这里插入图片描述



单调栈结构

给定一个不含有重复值的数组 arr,找到每一个 i 位置左边和
右边离 i 位置最近且值比 arr[i] 小的位置。返回所有位置相应的信息。

无重复值

在这里插入图片描述

在这里插入图片描述


import java.util.Scanner;
import java.util.Stack;

//没有重复值的单调栈
public class DanDiaoStack {

	public static void main(String[] args) {
		Scanner scan=new Scanner(System.in);
		int N=scan.nextInt();
		scan.nextLine();
		String[] s=scan.nextLine().split(" ");
		int[] num=new int[N];
		for(int i=0;i<N;++i) {
			num[i]=Integer.parseInt(s[i]);
		}
		int[][] lessIndex=new int[N][2];//存放每个数左右两边比它小的最近的位置
		Stack<Integer>st=new Stack<>();
		for(int i=0;i<N;++i) {
			if(st.isEmpty()||num[st.peek()]<num[i]) {
				st.push(i);
			}
			else {
				while(!st.isEmpty()&&num[i]<num[st.peek()]) {
					
					int cur=st.pop();
					lessIndex[cur][1]=i;
					if(st.isEmpty()) {
						lessIndex[cur][0]=-1;
					}
					else lessIndex[cur][0]=st.peek();
				}
				st.push(i);
			}
		}
		while(!st.isEmpty()) {
			int cur=st.pop();
			lessIndex[cur][1]=-1;
			if(st.isEmpty()) {
				lessIndex[cur][0]=-1;
			}
			else lessIndex[cur][0]=st.peek();
		}
		for(int i=0;i<N;++i) {
			System.out.println(lessIndex[i][0]+" "+lessIndex[i][1]);
		}
	}
}

在这里插入图片描述



有重复值



import java.util.LinkedList;
import java.util.Scanner;
import java.util.Stack;

//有重复值的单调栈
public class Main {

	public static void main(String[] args) {
		Scanner scan=new Scanner(System.in);
		int N=scan.nextInt();
		scan.nextLine();
		String[] s=scan.nextLine().split(" ");
		int[] num=new int[N];
		for(int i=0;i<N;++i) {
			num[i]=Integer.parseInt(s[i]);
		}
		int[][] lessIndex=new int[N][2];//存放每个数左右两边比它小的最近的位置
		Stack<LinkedList<Integer>>st=new Stack<>();
		for(int i=0;i<N;++i) {
			if(st.isEmpty()||num[st.peek().peekFirst()]<num[i]) {
				st.push(new LinkedList<>());
				st.peek().add(i);
			}
			else if(st.isEmpty()||num[st.peek().peekFirst()]==num[i]) {
				st.peek().addLast(i);
			}
			else {
				while(!st.isEmpty()&&num[i]<num[st.peek().peekFirst()]) {
					
					LinkedList<Integer>list=st.pop();
					for(Integer o:list) {
						lessIndex[o][1]=i;
						if(st.isEmpty()) {
							lessIndex[o][0]=-1;
						}else lessIndex[o][0]=st.peek().peekLast();
					}
					
					
				}
				st.push(new LinkedList<>());
				st.peek().add(i);
			}
		}
		while(!st.isEmpty()) {
			LinkedList<Integer>list=st.pop();
			for(Integer o:list) {
				lessIndex[o][1]=-1;
				if(st.isEmpty()) {
					lessIndex[o][0]=-1;
				}else lessIndex[o][0]=st.peek().peekLast();
			}
		}
		for(int i=0;i<N;++i) {
			System.out.println(lessIndex[i][0]+" "+lessIndex[i][1]);
		}
	}
}


在这里插入图片描述



指标A的最大值

在这里插入图片描述

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 找到指标A最大的值
     * @param arr int整型一维数组 给定的数组
     * @return int整型
     */
     public static int[][] getLessIndexArray(int[] arr){
	        int N=arr.length;
	        int[][] lessIndex=new int[N][2];//存放每个数左右两边比它小的最近的位置
			Stack<LinkedList<Integer>>st=new Stack<>();
			for(int i=0;i<N;++i) {
				if(st.isEmpty()||arr[st.peek().peekFirst()]<arr[i]) {
					st.push(new LinkedList<>());
					st.peek().add(i);
				}
				else if(st.isEmpty()||arr[st.peek().peekFirst()]==arr[i]) {
					st.peek().addLast(i);
				}
				else {
					while(!st.isEmpty()&&arr[i]<arr[st.peek().peekFirst()]) {
						
						LinkedList<Integer>list=st.pop();
						for(Integer o:list) {
							lessIndex[o][1]=i;
							if(st.isEmpty()) {
								lessIndex[o][0]=-1;
							}else lessIndex[o][0]=st.peek().peekLast();
						}
						
						
					}
					st.push(new LinkedList<>());
					st.peek().add(i);
				}
			}
			while(!st.isEmpty()) {
				LinkedList<Integer>list=st.pop();
				for(Integer o:list) {
					lessIndex[o][1]=-1;
					if(st.isEmpty()) {
						lessIndex[o][0]=-1;
					}else lessIndex[o][0]=st.peek().peekLast();
				}
			}
			return lessIndex;
	    }
    public int max (int[] arr) {
        // write code here
        int[][] lessIndex=getLessIndexArray(arr);
	    int ans=0;
	    for(int i=0;i<arr.length;++i){
	        int sum=0;
	        int j=lessIndex[i][0]+1;
	        if(j<0) j=0;
	        int end=lessIndex[i][1];
	        if(lessIndex[i][1]==-1) {
	            end=arr.length;
	        }
	        for(;j<end;++j){
	           sum+=arr[j];
	        }
	        if(sum==0)sum=arr[i];
	        ans=ans>sum*arr[i]?ans:sum*arr[i];
	   }
	   return ans;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值