LeetCode-Day30——栈
456. 132模式
给定一个整数序列:a1, a2, …, an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj。设计一个算法,当给定有 n 个数字的序列时,验证这个序列中是否含有132模式的子序列。
注意:n 的值小于15000。
示例1:
1 | 输入: [1, 2, 3, 4] |
示例 2:
1 | 输入: [3, 1, 4, 2] |
示例 3:
1 | 输入: [-1, 3, 2, 0] |
思路:
这里主要是采取栈的思想。
从vector末尾开始遍历,栈顶存放的是当前的最大值,如果nums[j] > max.top()
,(假设max.top()
在vector中原始的下标是k
),则现在已经满足了j < k && nums[j] > nums[k]
,即已经满足了32 模式,此时,在往下找,如果i
对应的nums[i]
小于third
,则算找到了i < j < k && nums[i] < nums[k] < nums[j]
。
Code如下:
1 | class Solution { |
496. 下一个更大元素I
给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出-1。
示例 1:
1 | 输入: nums1 = [4,1,2], nums2 = [1,3,4,2]. |
示例 2:
1 | 输入: nums1 = [2,4], nums2 = [1,2,3,4]. |
注意:
nums1和nums2中所有元素是唯一的。
nums1和nums2 的数组大小都不超过1000。
递增栈(从栈顶到栈底增加):
-
元素入栈之后,其下面元素一定是其左边第一个比它大的数(可用来求每个元素左边更大的第一个元素)
-
若在元素插入之前,栈顶元素比插入元素小,那么栈顶元素一定是插入元素左边第一个比它小的数
-
若在元素插入之前,栈顶元素比插入元素小,那么待插入元素是所有需要出栈的元素右边第一个更大的元素(可用来求每个元素右边更大的第一个元素)
-
最后一定会留下最大的数(对较大的数更有利)
递减栈也同理。
所以,这道题就是这样一个递增栈,我们从vector末尾开始遍历容器,当前的元素比栈顶元素要大的时候,则应该不断的弹栈,直到遇到一个比当前元素更大的栈顶元素或者栈已经为空的时候,如果栈顶为空,则说明,该元素右边不存在比它大的元素,如果栈顶不为空,则说明,栈顶元素就是该元素右边第一个比它大的元素。
如果当前的元素小于栈顶元素,则直接入栈。(因为当前的栈顶元素就是当前元素右边第一个比他大的数字)
Code如下:
1 | vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) { |
503. 下一个更大元素II
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
示例 1:
1 | 输入: [1,2,1] |
思路:
下次遇到循环数组,可以多复制一遍原数组
方法一. 栈
依然还是采用栈的想法
给你一个数组[2,1,2,4,3]
,你返回数组[4,2,4,-1,4]
。拥有了环形属性之后,最后一个元素3绕了一圈后找到了比自己大的元素4。
首先,计算机的内训都是线性的,没有真正意义上的换型数组,但是我们可以模拟出环形数组的效果,一般都是通过%
运算求模(余数),获得环形特效:
回到这个问题,增加了环形属性之后,问题的难点在于:这个Next
数组的意义不仅仅是当前元素的右边了,有可能出现在当前元素的左边(如上例)
我们可以考虑这样的思路:
将原始数组“翻倍”,就是在后面再接一个原始数组,这样的话,按照之前“比身高”的流程,每个元素不仅可以比较自己右边的元素,而且也可以和左边的元素比较了
如何实现?首先是将这个双倍数组构造出来,然后套用算法模板,但是我们可以不构造新数组,而是利用循环数组的技巧来模拟。
上Code:
1 | vector<int> nextGreaterElements(vector<int>& nums) { |
方法二.
就是我们在计算当前元素(nums[i])
的下一个比他大的元素的时候,可以先看看nums[i + 1]
是否比它大,如果nums[i + 1]
比它大,则说明nums[i]
下一个比它大的元素就是nums[i + 1]
,若不是,就比较result[i + 1]
,如果result[i + 1] > nums[i]
,则说明比nums[i]
大的下一个元素就是result[i + 1]
,如果还不是,就接着往下比较result[i + 2]...
如果已经到最后一个元素的话,就说明他右边已经没有元素比他大了,因此从左边开始遍历,寻找比他大的元素。
Code实现:
1 | vector<int> nextGreaterElements(vector<int>& nums) { |