leetcode
leetcode 2101 ~ 2150
下一个更大元素 IV

下一个更大元素 IV

难度:

标签:

题目描述

代码结果

运行时间: 138 ms, 内存: 28.4 MB


/*
 * 思路:
 * 使用Java Stream API来解决这个问题并不直观,因此我们会首先尝试常规方法来找到所有第二大元素的位置,然后通过Stream API输出结果。
 */
import java.util.Arrays;
import java.util.stream.IntStream;

public class Solution {
    public int[] secondGreaterElement(int[] nums) {
        int n = nums.length;
        int[] result = new int[n];
        Arrays.fill(result, -1); // 初始化为-1
        for (int i = 0; i < n; i++) {
            boolean foundFirst = false;
            for (int j = i + 1; j < n; j++) {
                if (nums[j] > nums[i]) {
                    if (foundFirst) {
                        result[i] = nums[j];
                        break;
                    }
                    foundFirst = true;
                }
            }
        }
        return IntStream.of(result).toArray(); // 使用Stream API转换结果数组
    }
}

解释

方法:

这个题解采用了单调栈的技巧来找出每个元素的第二大元素。核心思想是使用两个栈 st1 和 st2,以及一个辅助栈 tmp。st1 用来存放遍历到的元素的下标,保证栈顶到栈底元素是单调递减的。st2 用于记录第一个大于栈内元素的下标,以便在找到第二个大于栈内元素时,快速进行更新。当遇到一个新元素 n 时,如果它大于 st2 栈顶元素所对应的值,说明找到了一个更大的第二元素,将其更新到结果数组 res 中。之后,如果新元素 n 大于 st1 栈顶元素,将这些元素移动到 tmp,因为需要继续寻找这些元素的第二大元素。最后,将遍历到的元素下标 i 压入 st1,并将 tmp 中元素转移回 st2,保持 st1 和 st2 的有效性。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在单调栈使用中,为什么选择在遇到一个新元素大于st1栈顶元素时,将其移至临时栈tmp中而不是直接处理或丢弃?
在算法中,移动st1栈顶元素至临时栈tmp而不是直接处理或丢弃的原因是为了保持st1的单调递减属性,并确保能够找到每个元素的第二大值。直接处理或丢弃会导致无法为这些元素找到第二大值,因为可能存在一个更大的元素在后面。将元素暂时存储在tmp中,允许在遇到更大的元素时进行正确更新,然后再将其重新压入st2以继续寻找第二大值。
🦆
算法中如何确保每个元素的第二大值只被更新一次,而不会因为后续元素再次更新导致错误?
算法通过使用两个栈st1和st2保证元素的第二大值只更新一次。st1栈用于跟踪遍历中遇到的元素索引,而st2栈跟踪已找到第一大元素的元素索引。当一个新元素n大于st2栈顶元素时,它被视为第二大元素并更新到结果数组中,然后从st2中移除,确保每个元素的第二大值只被更新一次。
🦆
st2栈的具体作用是什么,它与st1栈在维护过程中有哪些不同的点?
st2栈的具体作用是记录已经找到第一个大元素的元素索引,为这些元素寻找第二大值。与st1不同的是,st1栈始终保持单调递减的顺序,只记录元素索引,不涉及到第二大值的寻找。当遇到一个新元素时,st1用于判断是否需要更新st2的元素。st2只有在找到新的更大元素时才会更新,并且一旦更新将不再包含该元素,保证每个元素的第二大值只更新一次。
🦆
为什么在最后处理完所有元素后,不需要对st1或st2中剩余的元素进行特殊处理?
在最后处理完所有元素后,不需要对st1或st2中剩余的元素进行特殊处理,因为这些剩余的元素在序列中没有找到更大的元素(对于st1)或第二大的元素(对于st2)。这意味着它们的最大或第二大元素不存在于数组中,根据题目要求这些元素的结果应当保持为初始化的-1,代表没有更大的元素。因此,直接保留这些元素的初始值即可。

相关问题