forked from azl397985856/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
lucifer
committed
Mar 24, 2021
1 parent
211404e
commit 92cf4be
Showing
3 changed files
with
112 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
## 题目地址(456. 132 模式) | ||
|
||
https://leetcode-cn.com/problems/132-pattern/ | ||
|
||
## 题目描述 | ||
|
||
``` | ||
给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。 | ||
如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false 。 | ||
进阶:很容易想到时间复杂度为 O(n^2) 的解决方案,你可以设计一个时间复杂度为 O(n logn) 或 O(n) 的解决方案吗? | ||
示例 1: | ||
输入:nums = [1,2,3,4] | ||
输出:false | ||
解释:序列中不存在 132 模式的子序列。 | ||
示例 2: | ||
输入:nums = [3,1,4,2] | ||
输出:true | ||
解释:序列中有 1 个 132 模式的子序列: [1, 4, 2] 。 | ||
示例 3: | ||
输入:nums = [-1,3,2,0] | ||
输出:true | ||
解释:序列中有 3 个 132 模式的的子序列:[-1, 3, 2]、[-1, 3, 0] 和 [-1, 2, 0] 。 | ||
提示: | ||
n == nums.length | ||
1 <= n <= 104 | ||
-109 <= nums[i] <= 109 | ||
``` | ||
|
||
## 前置知识 | ||
|
||
- [单调栈](../thinkings/monotone-stack.md) 🆕 | ||
|
||
## 公司 | ||
|
||
- 暂无 | ||
|
||
## 思路 | ||
|
||
132 模式指的是满足:大小关系是 1 < 2 < 3 ,索引关系是 1 < 3 < 2 的三个数。 | ||
|
||
一个简单的思路是使用一层**从左到右**的循环固定 3,遍历的同时维护最小值,这个最小值就是 1(如果固定的 3 不等于 1 的话)。 接下来使用另外一个嵌套寻找枚举符合条件的 2 即可。 这里的符合条件指的是大于 1 且小于 3。这种做法的时间复杂度为 $O(n^2)$,并不是一个好的做法,我们需要对其进行优化。 | ||
|
||
实际上,我们也可以枚举 2 的位置,这样目标变为找到一个大于 2 的数和一个小于 2 的数。由于 2 在序列的右侧,因此我们需要**从右往左**进行遍历。又由于题目只需要找到一个 312 模式,因此我们应该贪心地选择尽可能大的 2(只要不大于 3 即可),这样才**更容易找到 1**(换句话说不会错过 1)。 | ||
|
||
首先考虑找到 32 模式。我们可以使用从右往左遍历,遇到一个比后一位大的数。我们就找到了一个可行的 32 模式。和上面思路类似,维护一个全局最小值即可,这样就不会错过答案。可是这样就无法做到前面提到的**贪心地选择尽可能大的 2**,我们选择的 2 实际上是尽可能小的 2。那如何找到尽可能大的并且比当前数小的 2 呢? | ||
|
||
其实,我们可以维护一个递增栈。每次遇到一个比栈顶大的数就 pop 栈,直到栈顶比当前数字还大。那么最后一次 pop 出去的就是满足条件的最大的 2 了。找到了 32 模式,接下来,我们只需要找到一个比 2 小的数就可以直接返回 True 了。 | ||
|
||
## 关键点 | ||
|
||
- 固定 2, 从右往左遍历,使用单调栈获取最大的小于当前数的 2,并将当前数作为 3 。 | ||
|
||
## 代码 | ||
|
||
- 语言支持:Python3 | ||
|
||
Python3 Code: | ||
|
||
```python | ||
|
||
class Solution: | ||
def find132pattern(self, nums: List[int]) -> bool: | ||
s2, stack = float("-inf"), [] | ||
|
||
for i in range(len(nums) - 1, -1, -1): | ||
if nums[i] < s2: | ||
return True | ||
while stack and stack[-1] < nums[i]: | ||
s2 = stack.pop() | ||
stack.append(nums[i]) | ||
return False | ||
|
||
|
||
``` | ||
|
||
**复杂度分析** | ||
|
||
令 n 为数组长度。 | ||
|
||
- 时间复杂度:$O(n)$ | ||
- 空间复杂度:$O(n)$ | ||
|
||
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。 | ||
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~ | ||
|
||
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 | ||
|
||
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。 | ||
|
||
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg) |