503. 下一个更大元素 II


ID: 221
TITLE: 最大正方形
TAG: 栈


方法一:暴力法(使用两倍长度的数组)[超出时间限制]

算法:
在这个方法中,我们使用一个数组 d o u b l e n u m s doublenums doublenums,它是两个 n u m s nums nums 数组连接形成的。若我们需要找出 n u m s [ i ] nums[i] nums[i] 的下一个更大的元素时,我们可以扫描 d o u b l e n u m s [ j ] doublenums[j] doublenums[j] 的所有的元素,满足 i < j < l e n g t h ( d o u b l e n u m s ) i < j < length(doublenums) i<j<length(doublenums)。若找到更大的元素则说明它是 nums[i] 的下一个更大元素。如果找不到这样的元素,则在 r e s res res 数组添加 -1 \text{-1} -1

复杂度分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)。在最坏的情况下,会扫描整个的 d o u b l e n u m s doublenums doublenums 数组(大小为 2n \text{2n} 2n)来寻找 n u m s nums nums 中元素的下一个更大元素。
  • 空间复杂度: O ( n ) O(n) O(n) d o u b l e n u m s doublenums doublenums 使用的空间大小为 2n \text{2n} 2n r e s res res 使用的空间大小为 n \text{n} n

方法二:优化的暴力法 [通过]

算法:
我们可以使用 % \text{\%} % 操作在 n u m s nums nums 数组中循环遍历,而不是用两个 n u m s nums nums 数组。对于每个元素 n u m s [ i ] nums[i] nums[i],我们从索引 ( i + 1 ) % n (i+1)\%n (i+1)%n 开始在 n u m s nums nums 数组(长度为 n n n)中搜索,并至多比较 n − 1 n-1 n1 个元素。满足 ( i + 1 ) % n ≤ j ≤ ( i + ( n − 1 ) ) % n (i+1)\%n ≤ j ≤ (i+(n-1))\%n (i+1)%nj(i+(n1))%n。我们寻找找到的第一个较大的元素。如果找不到这样的元素,则在 r e s res res 数组中添加 -1 \text{-1} -1

复杂度分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)。在最坏的情况下,会扫描整个 n u m s nums nums 数组,来找到所有答案。
  • 空间复杂度: O ( n ) O(n) O(n) r e s res res 所使用的空间大小。

方法三:栈 [通过]

算法:

  • 该方法使用栈。栈中存储 n u m s nums nums 数组中相应元素的索引。栈顶存放到目前为止找到的下一个较大元素的索引。我们存储索引而不是元素,因为 n u m s nums nums 数组中可能有重复项。
  • 我们开始从右向左遍历 n u m s nums nums 数组。对于 n u m s [ i ] nums[i] nums[i],若 n u m s [ s t a c k [ t o p ] ] ≤ n u m s [ i ] nums\big[stack[top]\big]≤nums[i] nums[stack[top]]nums[i] 则弹出 s t a c k [ t o p ] stack[top] stack[top],直到 n u m s [ s t a c k [ t o p ] ] > n u m s [ i ] nums\big[stack[top]\big]>nums[i] nums[stack[top]]>nums[i] s t a c k [ t o p ] stack[top] stack[top] 代表的是 n u m s [ i ] nums[i] nums[i] 的下一个更大元素。
  • 如果栈顶没有元素,则意味着没有比在 n u m s [ i ] nums[i] nums[i] 的右边没有比 n u m s [ i ] nums[i] nums[i] 更大的元素。则我们将 n u m s [ i ] nums[i] nums[i] 的索引插入到栈的顶部,即 i i i,这样 n u m s [ i ] nums[i] nums[i](或 s t a c k [ t o p ] stack[top] stack[top])充当其左侧的元素的下一个更大的元素。
  • 我们在 n u m s nums nums 数组遍历两次。这样做是为了完成对 n u m s nums nums 数组的循环遍历。第一次遍历可能会在 r e s res res 数组中产生一些错误的答案,因为它只考虑位于 n u m s [ i ] nums[i] nums[i] 右侧的元素,而没有考虑循环遍历的条件。但是,这些答案会在第二次遍历中被更正。

为了确保方法的正确性,让我们看看下面的例子。
503. 下一个更大元素 II_第1张图片
503. 下一个更大元素 II_第2张图片
503. 下一个更大元素 II_第3张图片
503. 下一个更大元素 II_第4张图片
503. 下一个更大元素 II_第5张图片
503. 下一个更大元素 II_第6张图片
503. 下一个更大元素 II_第7张图片
503. 下一个更大元素 II_第8张图片
503. 下一个更大元素 II_第9张图片
503. 下一个更大元素 II_第10张图片
503. 下一个更大元素 II_第11张图片
503. 下一个更大元素 II_第12张图片
503. 下一个更大元素 II_第13张图片
503. 下一个更大元素 II_第14张图片
503. 下一个更大元素 II_第15张图片
503. 下一个更大元素 II_第16张图片
503. 下一个更大元素 II_第17张图片
503. 下一个更大元素 II_第18张图片
503. 下一个更大元素 II_第19张图片
503. 下一个更大元素 II_第20张图片
503. 下一个更大元素 II_第21张图片
503. 下一个更大元素 II_第22张图片
503. 下一个更大元素 II_第23张图片
503. 下一个更大元素 II_第24张图片

我们可以看到动画中,在第一次遍历之后, r e s res res 数组中有许多错误的答案(标记为 -1 \text{-1} -1),因为到目前为止只考虑了位于右边(非循环)的元素。但是,在第二次遍历之后,将替换成正确的值。

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)。遍历了 n u m s nums nums 数组两次。
  • 空间复杂度: O ( n ) O(n) O(n),栈和 r e s res res 的大小均为 n n n

你可能感兴趣的:(503. 下一个更大元素 II)