LeetCode 132模式问题:为何无法使用单调递增栈?
针对LeetCode 132模式问题(要求找到索引i < j < k,满足nums[i] < nums[k] < nums[j]),现有主流解法采用单调递减栈,但尝试使用单调递增栈实现时遇到问题:思路是让栈顶存储最大的k候选,同时记录栈中元素对应的前置最小值,但代码无法通过测试用例[1,4,0,-1,-2,-3,-1,-2]。
用户实现代码如下:
stack = [(nums[0], nums[0])] # num, min value curMin = nums[0] # mono increasing stack for num in nums[1:]: if stack and num < stack[-1][0]: if num > stack[-1][1]: return True else: stack.append((num, curMin)) curMin = min(curMin, num) return False
代码失效的核心原因
1. 栈的维护逻辑遗漏大量候选元素
你的代码仅在num >= 栈顶元素时才将元素入栈,导致测试用例中的0、-1、-2、-3、-1这些元素都未被加入栈中。而这些元素恰恰可能作为132模式中的j或k候选,直接被遗漏后,后续自然无法检测到对应的有效组合(比如测试用例中i=5(-3)、j=6(-1)、k=7(-2)的合法132模式)。
2. 检测逻辑仅局限于栈顶元素,覆盖范围不足
当前代码只检查当前num与栈顶元素的关系,但132模式的j可能存在于栈的任意位置,而非仅栈顶。比如测试用例中合法组合的j=-1未被入栈,即便入栈,你的逻辑也不会遍历栈中所有元素去匹配num > 对应min且num < 对应num的条件,只会检查栈顶,导致漏检。
3. 前置最小值的关联逻辑有误
你记录的curMin是全局遍历到当前位置的最小值,但栈中存储的是入栈时的全局最小值,而非每个元素左侧专属的最小值。当处理后续元素时,无法准确关联到某个j对应的i候选(即该j左侧的最小值),导致判断条件失效。
为什么单调递增栈不适合这个问题
132模式的核心是找nums[k]介于nums[i]和nums[j]之间,且i<j<k。单调递减栈的优势在于可以从后往前遍历,维护j的候选(较大的元素),同时记录当前最大的nums[k],能高效匹配nums[i] < nums[k] < nums[j]的条件。而单调递增栈从前往后遍历时,很难同时维护j的候选池和对应的i最小值,容易遗漏中间元素,且检测逻辑无法覆盖所有可能的组合,导致效率和正确性都难以保障。
内容的提问来源于stack exchange,提问作者user23326282

