leetcode
leetcode 2401 ~ 2450
数组是否表示某二叉树的前序遍历

数组是否表示某二叉树的前序遍历

难度:

标签:

题目描述

代码结果

运行时间: 92 ms, 内存: 52.4 MB


/*
 * LeetCode 2764: Verify if an array represents the preorder traversal of a binary tree
 * 
 * Approach using Java Streams:
 * While Java Streams are more suited for functional operations on collections,
 * this problem requires state tracking (lowerBound) and a stack for validation.
 * Hence, using streams here would be less intuitive and more convoluted.
 * We can use a stream to iterate over the array, but state changes make it impractical.
 */

import java.util.Stack;
import java.util.Arrays;

public class Solution {
    public boolean verifyPreorder(int[] preorder) {
        Stack<Integer> stack = new Stack<>();
        int[] lowerBound = {Integer.MIN_VALUE};
        return Arrays.stream(preorder).allMatch(value -> {
            if (value < lowerBound[0]) {
                return false;
            }
            while (!stack.isEmpty() && value > stack.peek()) {
                lowerBound[0] = stack.pop();
            }
            stack.push(value);
            return true;
        });
    }
}

解释

方法:

此题解使用栈的数据结构来验证数组是否表示某二叉树的前序遍历。对于给定的节点数组,每个节点表示为[i, j],其中i是节点值,j是其父节点值。解法的核心思想是从左到右遍历节点数组,利用栈来维护一个从根节点到当前节点的路径。对于每个节点,如果栈顶元素(即当前父节点)不等于该节点的父节点j,那么就不断弹栈,直到栈顶的元素等于j或者栈为空。如果栈为空,则说明没有找到对应的父节点,返回false。如果找到了,则将当前节点i压入栈中,继续处理下一个节点。遍历结束后,如果没有提前返回false,则说明数组表示的是一种前序遍历。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在初始时将-1压入栈中,它在算法中扮演了什么角色?
在算法中,-1被压入栈底用来表示一个虚拟的根节点的父节点。这做法主要是为了处理真实根节点(数组中的第一个节点)的情况,即使它没有显式的父节点。当处理到数组的第一个节点时,栈中除了-1没有其他元素,这样可以保证栈非空,使得根节点可以正确入栈。这也确保了在寻找父节点时栈不会为空,避免了额外的空栈检查。
🦆
在遍历过程中,如果栈顶元素不是当前节点的父节点时,持续弹栈的逻辑是基于什么考虑?
持续弹栈的逻辑基于前序遍历的特性,即一个节点之后紧跟着的是它的子节点。在前序遍历中,如果下一个节点不是当前节点的直接子节点,那么它可能是当前节点的兄弟节点或更远的祖先的其他子节点。因此,如果栈顶元素不是当前节点的父节点,我们需要通过弹栈来回溯到正确的父节点,以正确地反映前序遍历的结构。这确保了每个节点都能正确地与其父节点对应,保持遍历的有效性。
🦆
在弹栈操作后,如果栈为空,为什么直接返回False?这是否意味着所有的节点必须有一个公共的祖先节点?
如果在弹栈操作后栈为空,则意味着没有找到当前节点的父节点,这违反了每个节点(除根节点外)都应有一个明确的父节点的前提。返回False是因为这种情况表明给定的数组无法反映一个有效的前序遍历的树结构。是的,这暗示了在有效的前序遍历中,所有的节点(除了根节点)确实有一个共同的祖先,即根节点。
🦆
此算法是否假设每个节点值都是唯一的?如果节点数组中存在重复的节点值,算法的逻辑是否需要调整?
是的,此算法假设每个节点值都是唯一的。这是因为算法使用节点值来确定栈的弹入和弹出操作,如果存在重复的节点值,将无法准确地匹配父节点与子节点的关系。如果节点值可以重复,算法需要调整以便能够处理重复值的情况,可能需要引入额外的标识符(如节点的唯一ID)来保持节点的唯一性,确保父子关系的正确建立。

相关问题