Java 中的下一个更大元素

2024年9月10日 | 阅读 9 分钟

在数组中,下一个更大的元素是指最接近且大于当前元素的元素。另外,下一个更大的元素应该出现在当前元素的后面。任务是返回整数数组中每个元素的下一个更大的元素。如果数组中的某个元素的下一个更大元素不存在,则为此元素打印适当的消息。为简单起见,我们假设输入数组中的所有元素都非负。让我们通过一个例子来理解。

输入

arr[] = {14, 16, 9, 90, 99, 2, 6, 19, 4}

带解释的输出

元素下一个更大的元素(NGE)原因
1416元素 16 紧跟在 14 后面。此外,16 大于 14。
1690大于 16 的元素是 90 和 99。但是,我们将选择 90,因为元素 90 是最接近元素 16 的。
990元素 90 紧跟在 9 后面。此外,90 大于 9。
9099元素 99 紧跟在 90 后面。此外,99 大于 90。
99未找到在元素 99 之后没有比 99 更大的元素了。
26元素 6 紧跟在 2 后面。此外,6 大于 2。
619元素 19 紧跟在 6 后面。此外,19 大于 6。
19未找到在元素 19 之后没有比 19 更大的元素了。
4未找到在元素 4 之后没有其他元素了。

注意 1:对于最后一个元素,下一个更大的元素将始终是 -1,因为在最后一个元素之后,我们没有其他元素了。

注意 2:对于按非递增顺序排序的输入数组,下一个更大元素的值将始终为 -1。这是因为从当前元素开始的下一个元素将始终小于或等于当前元素,因为元素是按非递减顺序排列的。

例如

输入

arr[] = {89, 60, 58, 45, 39, 36, 20}

带解释的输出

输入数组所有元素的下一个更大元素都是 -1。

对于数字 89,没有元素出现在 89 之后且大于 89。

对于数字 60,没有元素出现在 60 之后且大于 60。

对于其他元素也可以给出类似的解释。

方法

有两种方法可以解决下一个更大的元素问题:一种是朴素方法,另一种是使用堆栈。让我们从朴素方法开始。

朴素方法

朴素方法很简单。你需要使用两个 for 循环。外层循环用于选择元素,内层循环用于将元素与选定的元素(当前元素)进行比较。当找到一个更大的元素(与当前元素比较后)时,内层循环会立即终止。观察以下程序。

文件名: NGE.java

输出

The input array is: 
14 16 9 90 99 2 6 19 4 

The next greater element for the element 14 is: 16
The next greater element for the element 16 is: 90
The next greater element for the element 9 is: 90
The next greater element for the element 90 is: 99
The next greater element for the element 99 does not exist. 
The next greater element for the element 2 is: 6
The next greater element for the element 6 is: 19
The next greater element for the element 19 does not exist. 
The next greater element for the element 4 does not exist.

时间复杂度:上面的程序使用了两个嵌套的 for 循环。因此,该程序的 time complexity 为 O(n2),其中 n 是输入数组中元素的总数。

空间复杂度:该程序没有使用任何额外的空间。因此,该程序的 space complexity 为 O(1)。

优化方法:使用堆栈

算法

步骤 1:将第一个元素压入堆栈。

步骤 2:逐个选择剩余的元素,并在循环中重复提到的子步骤。

  1. 将当前元素视为下一个。
  2. 如果堆栈不为空,则比较堆栈的顶部元素和下一个元素。
  3. 如果下一个元素大于堆栈的顶部元素,则从堆栈中弹出该元素。下一个元素是弹出元素的下一个更大的元素。
  4. 如果弹出的元素小于下一个元素,则继续从堆栈中弹出元素。对于所有这些弹出的元素,下一个元素将成为下一个更大的元素。

步骤 3:最终,堆栈中的下一个元素被压入。

步骤 4:在步骤 2 中提到的循环完成后,继续从堆栈中弹出所有剩余的元素,并为它们显示 -1,因为它们没有下一个更大的元素。

文件名: NGE1.java

输出

The input array is: 
14 16 9 90 99 2 6 19 4 

The next greater element for the element 14 is: 16
The next greater element for the element 9 is: 90
The next greater element for the element 16 is: 90
The next greater element for the element 90 is: 99
The next greater element for the element 2 is: 6
The next greater element for the element 6 is: 19
The next greater element for the element 4 does not exist.
The next greater element for the element 19 does not exist.
The next greater element for the element 99 does not exist.

时间复杂度:该程序的 time complexity 为 O(n),其中 n 是数组中元素的总数。

空间复杂度:该程序的 space complexity 为 O(n),其中 n 是数组中元素的总数。

我们看到输出中数字出现的顺序与输入数组中的顺序不同。为了保持顺序,需要反向遍历。观察以下程序。

文件名: NGE2.java

输出

The input array is: 
14 16 9 90 99 2 6 19 4 

The next greater element for the element 14 is: 16
The next greater element for the element 16 is: 90
The next greater element for the element 9 is: 90
The next greater element for the element 90 is: 99
The next greater element for the element 99 does not exist.
The next greater element for the element 2 is: 6
The next greater element for the element 6 is: 19
The next greater element for the element 19 does not exist.
The next greater element for the element 4 does not exist.

时间复杂度:该程序的 time complexity 为 O(n),其中 n 是数组中元素的总数。

空间复杂度:该程序的 space complexity 为 O(n),其中 n 是数组中元素的总数。