返回

轻松掌握:通过单调栈快速找到每个小朋友的好朋友

前端

单调栈:数据结构中的隐藏力量

单调栈的本质

单调栈是一种栈式数据结构,其元素遵循单调递增或递减的顺序。与普通栈只允许从栈顶操作不同,单调栈仅支持在栈顶添加或删除元素,同时保持栈中元素的单调性。

单调栈的应用场景

单调栈在解决各种算法问题时具有广泛的应用,其中一个引人注目的例子便是寻找小朋友的好朋友问题:

寻找好朋友:单调栈的实践

设想一群小朋友排队,每个小朋友都有一个身高。我们需要找到每个小朋友第一个比他更高个子的好朋友。为了解决这个问题,我们巧妙地利用单调栈来维护一个递减的序列,其中包含所有小朋友的身高。

算法步骤:

  1. 构建单调栈: 将所有小朋友按照身高降序排列,并依次压入栈中。此时,栈顶的小朋友就是当前最高的小朋友。

  2. 寻找好朋友: 当我们处理下一个小朋友时,需要检查栈顶的小朋友是否比当前小朋友高。如果是,那么栈顶的小朋友就是当前小朋友的好朋友,我们将该位置输出即可。

  3. 继续压栈: 如果栈顶的小朋友不是当前小朋友的好朋友,那么我们将栈顶的小朋友弹出栈,并继续检查下一个栈顶的小朋友,直到找到当前小朋友的好朋友或栈空为止。

Java代码示例:

import java.util.Stack;

public class FindFriends {

    public static int[] findFriends(int[] height) {
        Stack<Integer> stack = new Stack<>();
        int[] friends = new int[height.length];

        for (int i = 0; i < height.length; i++) {
            while (!stack.isEmpty() && height[stack.peek()] <= height[i]) {
                friends[stack.pop()] = i;
            }
            stack.push(i);
        }

        while (!stack.isEmpty()) {
            friends[stack.pop()] = 0;
        }

        return friends;
    }

    public static void main(String[] args) {
        int[] height = {1, 2, 3, 4, 5, 1, 2, 3};
        int[] friends = findFriends(height);

        for (int friend : friends) {
            System.out.print(friend + " ");
        }
    }
}

单调栈的魅力

单调栈算法在解决找朋友问题时展现了其出色的复杂性和连贯性。通过维护一个递减序列,它能够高效地找到每个小朋友的好朋友,无需遍历整个数组。这种巧妙的设计大大降低了时间复杂度,使其成为该问题的理想解决方案。

常见问题解答

1. 单调栈有什么其他应用?

除了寻找好朋友问题,单调栈还广泛应用于其他场景,例如求最大值/最小值、求最长递增/递减子序列、求最近较小值/较大值、求历史最大值/最小值等。

2. 单调栈的优点是什么?

单调栈的优点包括复杂度低、操作简单、实现方便,以及可以处理各种单调性问题。

3. 单调栈有什么局限性?

单调栈只适用于单调性问题,不适用于其他类型的算法问题。

4. 如何设计单调栈算法?

设计单调栈算法需要明确问题的单调性要求,然后利用栈的特性设计出算法步骤,确保在栈中始终保持单调性。

5. 单调栈在实际应用中有哪些案例?

单调栈在实际应用中广泛用于图像处理、数据分析、股票交易等领域,其高效的性能使其成为各种问题的理想解决方案。