123模式

Posted Myuniverse

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了123模式相关的知识,希望对你有一定的参考价值。

超级暴力解法

思路:循环三次

func find132pattern1(nums []int) bool {
	if len(nums)<=2{
		return false
	}

	for i:=0;i<len(nums);i++{
		for j:=i+1;j<len(nums);j++{
			for k:=j+1;k<len(nums);k++{
				if nums[i] < nums[k] && nums[k] < nums[j]{
					return true
				}
			}
		}
	}

	return false
}

结果:超时

优化解法

上面的做法是分别对三个数进行枚举,这样做法是O(n3)的,数据范围是104,稳稳的超时。

因此,我们可以从132的大小特性去分析,如果在确定一个数之后,如何快速找到另外两个数(我们使用ijk来指代132结构):

  • 枚举i:由于i是132结构中最小的数,那么相当于我们要从i后面,找到一个对数(j,k),是的(j,k)都满足比i大,同时j和k之间存在j>k的关系。由于我们遍历是单向的,因此我们可以将问题转化为找k,首先k需要比i大,同时在[i,k]之间存在比k大的数
  • 枚举 j:由于 j 是 132 结构里最大的数,因此我们需要在 j 的右边中比 j 小的「最大」的数,在 j 的左边找比 j 小的「最小」的数。这很容易联想到单调栈,但是朴素的单调栈是帮助我们找到左边或者右边「最近」的数,无法直接满足我们「最大」和「最小」的要求,需要引入额外逻辑。
  • 枚举 k:由于 k 是 132 结构中的中间值,这里的分析逻辑和「枚举 i」类似,因为遍历是单向的,我们需要找到 k 左边的 i,同时确保 [i,k] 之间存在比 i 和 k 大的数字。

以上三种分析方法都是可行的,这里只做枚举i的做法。

过程:我们从后往前做,维护一个「单调递减」的栈,同时使用 k 记录所有出栈元素的最大值(k 代表满足 132 结构中的 2)。

那么当我们遍历到 i,只要满足发现满足 nums[i] < k,说明我们找到了符合条件的 i j k。

举个

以上是关于123模式的主要内容,如果未能解决你的问题,请参考以下文章

[Go] 通过 17 个简短代码片段,切底弄懂 channel 基础

用于从 cloudkit 检索单列的代码模式/片段

如何在 Javadoc 中使用 @ 和 符号格式化代码片段?

iOS通过代码将默认键盘从ABC模式切换到123模式?

尝试使用片段保存夜间模式状态

是否有在单个活动中处理多个片段的 Android 设计模式?