LeetCode(456 132模式)

如题在这里插入图片描述
首线肯定是可以用多重循环来做。但是想偷懒,用缓存化的思想来做。由题意是找到匹配即可,那么我们尽可能使用匹配程度更大的条件去匹配,那么有两种方向,一种是正向遍历,那么就是用大和小去匹配中,一种是倒序用大和中区匹配小。第一种对于匹配条件的更新存在麻烦 譬如 35 02 序列 这时候就需要匹配两段了,于是选择第二种。

public static boolean find132pattern(int[] nums) {
		if (nums == null || nums.length < 3) {
			return false;
		} // 更新更大的max和min 难点在于min的取值
		int start = nums[nums.length - 1];  //最后一个元素
		int min = nums[nums.length - 1];	//后段符合的第二大元素
		int max = nums[nums.length - 1];	//后段符合的最大元素
		int mai = 0; //前序所有波峰的前一位最大元素index
		int mii =0;	//第一轮若为递减则缓存第一个波谷的index
		int bf = nums[nums.length - 1]; // 后一位元素
		int flag = 0; // 前序变化方向 1递增 -1递减
		int flag2 = 0; // 是否相等
		int flag3 = 0; // 第一轮变化标志,找到第一个波峰则变为1
		int bc = 0; //相等出现次数缓存
		for (int i = nums.length - 2; i >= 0; i--) {
			int num = nums[i];
			if (num > bf) { // 递增
				if (flag == -1) { // 前序递减 即为波谷
					if (flag3 == 0) { //第一次检索为波谷
						min = bf;
						mii=i+1;
					}
					if (flag3 == 1 && bf < min) { // 前序存在波峰且该波谷小于min
						return true;
					}
				}
				flag = 1;
				flag2 = 0;
				bc = 0;
				bf = num;
			} else if (num < bf) { // 递减
				if (flag == 1) { // 前序递增 即波峰
					if (flag3 == 0) { // 前序不存在波峰
						max = bf; // max即为bf min需综合判断
						min = nums[i + 2 + bc]; // min初始为波峰后一位
						if (max > start) { // 波峰大于最后一位
							min = Math.max(start, min);// 更新min为最后位与min缓存的较大者
						} else { // 否则需遍历前段
							for (int m = nums.length - 1; m >= mii; m--) {
								if (nums[m] < bf) { // 找到小于波峰的最大一位
									min = Math.max(min, nums[m]); // 该位元素与缓存的较大值
									break;
								}
							}
						}
						mai =i;
						flag3 = 1;
					} else if (bf > max) { // 波峰更高
						// min综合判断
						min = Math.max(max, nums[i + 2 + bc]); // 前段波峰与及当前波峰前一位较大值
						max = bf;// 更新max
						if (min < start) { // 缓存值
							for (int m = nums.length - 1; m >= mii; m--) {
								if (nums[m] < bf) { // 同样找到小于波峰最大一位
									min = Math.max(min, nums[m]);
									break;
								}
							}
						}						
					} else if (Math.max(nums[mai], nums[i + 2 + bc]) > min) { //前一波峰前一位与当前
						min = Math.max(nums[mai], nums[i + 2 + bc]);	//后一位的较大值大于min,则更新
						max = bf;
					}
					mai = nums[i]>nums[mai] ? i:mai;  //当前i为波峰前一位,判断是否需要更新
				}				
				bf = num;
				flag = -1;
				flag2 = 0;
				bc = 0;
			} else {		//相等		
				flag2 = 1;			
				bf = num;
				bc++;	//记录相等出现次数
			}
		}
		if (flag3 == 1 && bf < min)
		{ // 对应结束时持续递减获得最小值
			return true;
		}
		return false;
	}

效果很好看,就是写出来真的头大,在这里插入图片描述
更新原则是尽可能获取到更大的次大值。但是这个次大值的匹配判断就很烦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值