题解 | LeetCode中树的遍历题目合集(144,589,94,145,590,102,107)

144. 二叉树的前序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode(var `val`: Int) {
 *      var left: TreeNode? = null
 *      var right: TreeNode? = null
 *  }
 */
import java.util.*

class Solution {
    fun preorderTraversal(root: TreeNode?): List<Int> {
        val result = ArrayList<Int>()
        val stack = Stack<TreeNode?>()
        stack.push(root)
        while (!stack.isEmpty()) {
            val node = stack.pop() ?: continue
            result.add(node.`val`)
            stack.push(node.right)
            stack.push(node.left)
        }
        return result
    }
}

思路

采用栈保存需要前序遍历的结点。每次pop一个结点,记录其val值后,将其子节点倒序压入栈中。

递归实现比较简单:

/**
 * Definition for a binary tree node.
 * public class TreeNode(var `val`: Int) {
 *      var left: TreeNode? = null
 *      var right: TreeNode? = null
 *  }
 */
class Solution {
    private val result = ArrayList<Int>()

    fun preorderTraversal(root: TreeNode?): List<Int> {
        pre(root)
        return result
    }

    private fun pre(root: TreeNode?) {
        if (root == null) return
        result.add(root.`val`)
        pre(root.left)
        pre(root.right)
    }
}

589. N叉树的前序遍历

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val,List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
    public List<Integer> preorder(Node root) {
        List<Integer> result = new ArrayList<>();
        Stack<Node> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            Node node = stack.pop();
            if (node == null) continue;
            result.add(node.val);
            for (Node child : reverse(node.children)) {
                stack.push(child);
            }
        }
        return result;
    }

    private List<Node> reverse(List<Node> nodes) {
        List<Node> result = new ArrayList<>();
        for (int i = 0; i < nodes.size(); i++) {
            result.add(nodes.get(nodes.size() - i - 1));
        }
        return result;
    }
}

思路

采用栈保存需要前序遍历的结点。每次pop一个结点,记录其val值后,将其子节点倒序压入栈中。

递归实现比较简单:

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val,List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
    private List<Integer> result = new ArrayList<>();

    public List<Integer> preorder(Node root) {
        pre(root);
        return result;
    }

    private void pre(Node root) {
        if (root == null) return;
        result.add(root.val);
        for (Node child : root.children) {
            pre(child);
        }
    }
}

94. 二叉树的中序遍历

/**
 * Example:
 * var ti = TreeNode(5)
 * var v = ti.`val`
 * Definition for a binary tree node.
 * class TreeNode(var `val`: Int) {
 *     var left: TreeNode? = null
 *     var right: TreeNode? = null
 * }
 */
import java.util.*

class Solution {
    private val result = mutableListOf<Int>()

    fun inorderTraversal(root: TreeNode?): List<Int> {
        root ?: return listOf()
        val stack = Stack<TreeNode?>().apply {
            push(root)
        }
        result.clear()
        inorderStack(stack)
        return result.toList()
    }

    fun inorderStack(stack: Stack<TreeNode?>) {
        while (true) {
            var node = stack.last()
            if (node != null) {
                stack.push(node.left)
            } else {
                // 弹出这个空结点
                stack.pop()
                if (stack.isEmpty()) break
                // 弹出栈顶的结点
                node = stack.pop() ?: continue
                result.add(node.`val`)
                stack.push(node.right)
            }
        }
    }
}

思路

栈保存应该遍历的结点顺序。如果一个结点不为空,将其左结点压入栈中,直到左结点压完后,弹出栈顶的结点,记录其值后,压入其右结点。

递归实现比较简单:

/**
 * Example:
 * var ti = TreeNode(5)
 * var v = ti.`val`
 * Definition for a binary tree node.
 * class TreeNode(var `val`: Int) {
 *     var left: TreeNode? = null
 *     var right: TreeNode? = null
 * }
 */
class Solution {
    private val result = mutableListOf<Int>()

    fun inorderTraversal(root: TreeNode?): List<Int> {
        inorder(root)
        return result.toList()
    }

    private fun inorder(node: TreeNode?) {
        node ?: return
        inorder(node.left)
        result.add(node.`val`)
        inorder(node.right)
    }
}

145. 二叉树的后序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.*

class Solution {
    private val result = mutableListOf<Int>()

    fun postorderTraversal(root: TreeNode?): List<Int> {
        root ?: return listOf()
        val stack = Stack<TreeNode?>()
        stack.push(root)
        result.clear()
        postorder(stack)
        return result.toList()
    }

    private fun postorder(stack: Stack<TreeNode?>) {
        while (!stack.isEmpty()) {
            val node = stack.pop() ?: return
            result.add(node.`val`)
            if (node.left != null) stack.push(node.left)
            if (node.right != null) stack.push(node.right)
        }
        result.reverse()
    }
}

思路

采用根右左的方式遍历树,然后将结果反转。

思路二:记录上一个访问的结点。如果是当前结点的子结点,说明其左右结点均已访问,将当前结点出栈。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.*

class Solution {
    private val result = mutableListOf<Int>()

    fun postorderTraversal(root: TreeNode?): List<Int> {
        root ?: return listOf()
        val stack = Stack<TreeNode?>()
        stack.push(root)
        result.clear()
        postorder(stack)
        return result.toList()
    }

    private fun postorder(stack: Stack<TreeNode?>) {
        var last: TreeNode? = null
        while (true) {
            val node = stack.last() ?: return
            if ((node.left == null && node.right == null) || (last != null && (last == node.left || last == node.right))) {
                result.add(node.`val`)
                last = node
                stack.pop()
                if (stack.isEmpty()) break
            } else {
                if (node.right != null) stack.push(node.right)
                if (node.left != null) stack.push(node.left)
            }
        }
    }
}

思路三:递归实现,比较简单。

/**
 * Example:
 * var ti = TreeNode(5)
 * var v = ti.`val`
 * Definition for a binary tree node.
 * class TreeNode(var `val`: Int) {
 *     var left: TreeNode? = null
 *     var right: TreeNode? = null
 * }
 */
class Solution {
    private val result = mutableListOf<Int>()

    fun postorderTraversal(root: TreeNode?): List<Int> {
        postorder(root)
        return result.toList()
    }

    private fun postorder(node: TreeNode?) {
        node ?: return
        postorder(node.left)
        postorder(node.right)
        result.add(node.`val`)
    }
}

590. N叉树的后序遍历

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val,List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
    public List<Integer> postorder(Node root) {
        Stack<Node> stack = new Stack<>();
        stack.push(root);
        return postorderStack(stack);
    }

    private List<Integer> postorderStack(Stack<Node> stack) {
        List<Integer> result = new ArrayList<>();
        while (!stack.isEmpty()) {
            Node node = stack.pop();
            if (node == null) continue;
            result.add(node.val);
            for (Node child : node.children) {
                stack.push(child);
            }
        }
        return reverse(result);
    }

    private List<Integer> reverse(List<Integer> integers) {
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < integers.size(); i++) {
            result.add(integers.get(integers.size() - i - 1));
        }
        return result;
    }
}

思路

与二叉树的后序遍历类似,采用根右左的方式遍历树,然后将结果反转。

102. 二叉树的层次遍历

/**
 * Example:
 * var ti = TreeNode(5)
 * var v = ti.`val`
 * Definition for a binary tree node.
 * class TreeNode(var `val`: Int) {
 *     var left: TreeNode? = null
 *     var right: TreeNode? = null
 * }
 */
class Solution {
    fun levelOrder(root: TreeNode?): List<List<Int>> {
        val result = mutableListOf<List<Int>>()
        var current = mutableListOf<TreeNode?>()
        current.add(root)
        while (!current.isEmpty()) {
            val children = mutableListOf<TreeNode?>()
            val list = mutableListOf<Int>()
            for (node in current) {
                node ?: continue
                list.add(node.`val`)
                children.add(node.left)
                children.add(node.right)
            }
            if (!list.isEmpty()) result.add(list.toList())
            current = children
        }
        return result
    }
}

思路

记录当前层级的结点,依次取值保存到list中,当前层级遍历完成后,将其计入result数组。
然后记录当前层级的子节点,迭代求list,直至整个遍历完成。

107. 二叉树的层次遍历 II

/**
 * Example:
 * var ti = TreeNode(5)
 * var v = ti.`val`
 * Definition for a binary tree node.
 * class TreeNode(var `val`: Int) {
 *     var left: TreeNode? = null
 *     var right: TreeNode? = null
 * }
 */
class Solution {
    fun levelOrderBottom(root: TreeNode?): List<List<Int>> {
        val result = mutableListOf<List<Int>>()
        var current = mutableListOf<TreeNode?>()
        current.add(root)
        while (!current.isEmpty()) {
            val children = mutableListOf<TreeNode?>()
            val list = mutableListOf<Int>()
            for (node in current) {
                node ?: continue
                list.add(node.`val`)
                children.add(node.left)
                children.add(node.right)
            }
            if (!list.isEmpty()) result.add(list.toList())
            current = children
        }
        return result.reversed()
    }
}

思路

记录当前层级的结点,依次取值保存到list中,当前层级遍历完成后,将其计入result数组。
然后记录当前层级的子节点,迭代求list,直至整个遍历完成后,翻转结果即可。

原创文章 67 获赞 68 访问量 6万+

猜你喜欢

转载自blog.csdn.net/AlpinistWang/article/details/88413603