671. Second Minimum Node In a Binary Tree

本文探讨了如何在特殊二叉树中寻找第二小的节点值。通过递归遍历,利用二叉树节点值的特点,高效地找到答案。

1. 原题

Given a non-empty special binary tree consisting of nodes with the non-negative value, where each node in this tree has exactly two or zero sub-node. If the node has two sub-nodes, then this node’s value is the smaller value among its two sub-nodes.

Given such a binary tree, you need to output the second minimum value in the set made of all the nodes’ value in the whole tree.

If no such second minimum value exists, output -1 instead.

Example 1:
Input:
2
/ \
2 5
/ \
5 7

Output: 5
Explanation: The smallest value is 2, the second smallest value is 5.
Example 2:
Input:
2
/ \
2 2

Output: -1
Explanation: The smallest value is 2, but there isn’t any second smallest value

2. 分析

  • 每个节点的值是左右子叶的一个最小值, 所以整棵树的根节点一定是最小的
  • 如果一个节点的左子树空, 也就是说这个节点只能由右子树产生, 反之一样
  • 如果一个节点和父节点的值一样, 继续分左右搜索, 不一样表示已经找到了候选值。因为到了这一层表示父节点所在的那一层的数和根节点一样, 所以这个节点需要和兄弟节点比较选一个小的就可以了

3. 代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int getSecond(TreeNode* root, int min){
        if (!root) return -1;
        /*
        *这里比较重要, 当发现有不等于根节点的数出现, 就可以返回传给上层函数(父节点的getSecond中的left 或者 right).
        */
        if (root->val != min) return root->val;
        int left = getSecond(root->left, min);
        int right = getSecond(root->right, min);
        if (left == -1) return right;
        if (right == -1) return left;
        return left>right?right:left;
    }

    int findSecondMinimumValue(TreeNode* root) {
        if (!root) return -1;
        int min = root->val;
        int ans = getSecond(root, min);
        return ans;
    }
};
<think>We are going to implement a binary tree in Python. We'll create a class for the tree nodes and then a class for the binary tree that will contain methods for inserting nodes and traversing the tree. The binary tree will support basic operations. We'll implement: - Node class: to represent each node in the tree (with data, left, and right). - BinaryTree class: with an initializer (root) and methods for insertion and traversals (in-order, pre-order, post-order). However, note that the user asked for an implementation of a binary tree. We'll focus on a simple binary tree (not binary search tree) for generality. But note: without ordering, insertion is arbitrary. Usually, we implement a binary search tree (BST) to have structure. Since the question does not specify, we'll do a basic binary tree and then show how to insert in a BST manner. Since the user mentioned "binary tree", we can implement a simple tree with a method to insert arbitrarily (for example, level order insertion). But more typically, when people ask for a binary tree they mean a BST. Let's clarify: we'll implement a BST. Steps for BST: - Each node has a value, and for any node, all values in the left subtree are less than the node's value, and all values in the right subtree are greater. We'll implement: - Node class: with value, left, right. - BinaryTree (BST) class: __init__: initializes root as None. insert(value): inserts a value into the BST. We'll also implement traversal methods: in-order, pre-order, post-order. Alternatively, we can also implement a method for level-order insertion (non-BST way) if the user wants a general binary tree. But the question is ambiguous. Since BST is the most common, we'll do BST. However, the user did not specify BST. To be safe, we'll implement a binary tree that can be built by inserting in a level-order fashion (like a complete tree). We can provide two versions? But the instruction says one solution. Since the question is "How do you implement a binary tree in Python?" without specifics, I'll provide a basic binary tree structure and then show insertion in BST style. Then note that we can also insert arbitrarily in non-BST ways, but the BST is a common use case. Decision: We'll create a Node class and then a BinaryTree class that supports: - BST insertion (so we call it BinarySearchTree) OR - Alternatively, we can do a general binary tree that doesn't enforce BST. But without structure, it's not very useful. Let me re-read the question: "How do you implement a binary tree in Python?" I'll provide a general binary tree node and then show how to build a tree by setting left and right. Then I'll show a BST as a special case. But to keep it simple, I'll implement a BST. Implementation for BST: class Node: def __init__(self, value): self.value = value self.left = None self.right = None class BinaryTree: def __init__(self): self.root = None def insert(self, value): if self.root is None: self.root = Node(value) else: self._insert_recursive(self.root, value) def _insert_recursive(self, node, value): if value < node.value: if node.left is None: node.left = Node(value) else: self._insert_recursive(node.left, value) else: # value >= node.value if node.right is None: node.right = Node(value) else: self._insert_recursive(node.right, value) Then traversal methods. But note: for a general binary tree (non-BST) we wouldn't have a natural insertion order. We might want to insert in the first available spot in level order. So let's do that if the user wants a general tree. However, the question is open. Since the user did not specify, I'll provide both and explain. But to keep the answer focused, I'll choose the BST as it's more structured. Alternatively, we can do: Option 1: BST (as above) Option 2: General binary tree with level-order insertion: We maintain the tree as a complete tree. We use a queue to find the first node that has an empty child (left or right) and insert there. Let's go with Option 2 for a general binary tree? The question just says "binary tree", so let me do a general one with level-order insertion. However, note: the question doesn't specify how to build the tree. We are just to create the data structure. So we can create the nodes and link them arbitrarily. But without an insertion method, the tree structure is built manually. How about: we implement a class for Node and then the user can build the tree by setting left and right? That's the most basic. But the user might want an insertion method. Since the question is ambiguous, I'll show a basic node structure and then a BST insertion as a common example. Let me structure the answer: We'll define a Node class that can form a binary tree by having left and right child references. Then, we'll create a BinaryTree class that holds the root and provides methods for traversal. Then, we'll add a method for BST insertion as an example of building the tree. Alternatively, if we want a general tree with level-order insertion, we can also provide that. To cover both, I'll implement: Node class (same for both) BinaryTree class that has: __init__(self, root=None) Then we'll have two insertion methods? But let's not complicate. Since the question is open, I'll show two separate examples. However, the instruction says: "How do you implement a binary tree". So the minimal implementation is: class Node: def __init__(self, key): self.left = None self.right = None self.val = key Then we can create nodes and link: root = Node(1) root.left = Node(2) root.right = Node(3) This is a binary tree. But to provide more value, I'll also show a BST with insertion method and traversals. I choose: we'll implement a BST with insertion and in-order traversal (which will give sorted order). Code: class Node: def __init__(self, value): self.value = value self.left = None self.right = None class BinaryTree: def __init__(self): self.root = None def insert(self, value): if self.root is None: self.root = Node(value) else: self._insert_recursive(self.root, value) def _insert_recursive(self, node, value): if value < node.value: if node.left is None: node.left = Node(value) else: self._insert_recursive(node.left, value) else: # value >= node.value if node.right is None: node.right = Node(value) else: self._insert_recursive(node.right, value) def in_order_traversal(self, node, result=None): if result is None: result = [] if node: self.in_order_traversal(node.left, result) result.append(node.value) self.in_order_traversal(node.right, result) return result Then we can also add pre-order and post-order. But note: the above BST insertion duplicates: we go left for <, and right for >=. This allows duplicates. If we don't want duplicates, we can choose to not insert duplicates? The question doesn't specify. Alternatively, we can disallow duplicates by: if value == node.value: return # or handle as desired Let's not handle duplicates for simplicity. However, the user might want a general tree. But the question is "binary tree", and BST is a kind of binary tree. So we'll present the BST implementation. Example usage: tree = BinaryTree() tree.insert(5) tree.insert(3) tree.insert(7) tree.insert(2) tree.insert(4) tree.insert(6) tree.insert(8) print(tree.in_order_traversal(tree.root)) # [2,3,4,5,6,7,8] We'll also add pre-order and post-order for completeness. Alternatively, we can also make the traversals as generators? But we'll return a list for simplicity. We'll add: def pre_order_traversal(self, node, result=None): if result is None: result = [] if node: result.append(node.value) self.pre_order_traversal(node.left, result) self.pre_order_traversal(node.right, result) return result def post_order_traversal(self, node, result=None): if result is None: result = [] if node: self.post_order_traversal(node.left, result) self.post_order_traversal(node.right, result) result.append(node.value) return result And we can also add level-order traversal (BFS) for completeness. Let's add: from collections import deque def level_order_traversal(self): result = [] queue = deque() if self.root: queue.append(self.root) while queue: node = queue.popleft() result.append(node.value) if node.left: queue.append(node.left) if node.right: queue.append(node.right) return result We'll now write the code accordingly. But note: the class name is BinaryTree but we are implementing a BST. We can call it BinarySearchTree? Not necessary, but let's call it BinaryTree and note that our insertion is for BST. Alternatively, we can make the insertion method customizable? Not now. Let's code accordingly. Summary: We implement a Node class and a BinaryTree class that is actually a BST. Steps: 1. Define Node. 2. Define BinaryTree with root. 3. Implement insert (for BST). 4. Implement traversals: in-order, pre-order, post-order, level-order. We'll write the code and then explain. Note: We are using recursion for insert and traversals. For large trees, recursion might hit recursion limit. Then we can use iterative methods. But for simplicity, we do recursion. Let's code. </think>### Binary Tree Implementation in Python A binary tree is a hierarchical data structure where each node has at most two children (left and right). Below is a complete implementation of a binary tree with insertion and traversal methods. #### Implementation ```python class Node: """Node class for binary tree elements""" def __init__(self, value): self.value = value self.left = None self.right = None class BinaryTree: """Binary Tree implementation with basic operations""" def __init__(self): self.root = None def insert(self, value): """Inserts a value into the tree (level-order insertion)""" new_node = Node(value) if not self.root: self.root = new_node return from collections import deque queue = deque([self.root]) while queue: current = queue.popleft() if not current.left: current.left = new_node return else: queue.append(current.left) if not current.right: current.right = new_node return else: queue.append(current.right) def inorder_traversal(self, node=None, result=None): """Returns nodes in Left -> Root -> Right order""" if result is None: result = [] if node is None: node = self.root if node.left: self.inorder_traversal(node.left, result) result.append(node.value) if node.right: self.inorder_traversal(node.right, result) return result def preorder_traversal(self, node=None, result=None): """Returns nodes in Root -> Left -> Right order""" if result is None: result = [] if node is None: node = self.root result.append(node.value) if node.left: self.preorder_traversal(node.left, result) if node.right: self.preorder_traversal(node.right, result) return result def postorder_traversal(self, node=None, result=None): """Returns nodes in Left -> Right -> Root order""" if result is None: result = [] if node is None: node = self.root if node.left: self.postorder_traversal(node.left, result) if node.right: self.postorder_traversal(node.right, result) result.append(node.value) return result # Example usage if __name__ == "__main__": tree = BinaryTree() values = [5, 3, 7, 2, 4, 6, 8] for val in values: tree.insert(val) print("In-order traversal:", tree.inorder_traversal()) # [2, 3, 4, 5, 6, 7, 8] print("Pre-order traversal:", tree.preorder_traversal()) # [5, 3, 2, 4, 7, 6, 8] print("Post-order traversal:", tree.postorder_traversal()) # [2, 4, 3, 6, 8, 7, 5] ``` #### Key Components Explained: 1. **`Node` Class**: - Stores a `value` and references to `left`/`right` child nodes. 2. **`BinaryTree` Class**: - **`insert(value)`**: Inserts values using **level-order traversal** (ensures the tree remains balanced). Uses a queue to find the first available slot. - **Traversal Methods**: - **`inorder_traversal`**: Left subtree → Root → Right subtree (returns sorted values for BSTs). - **`preorder_traversal`**: Root → Left subtree → Right subtree. - **`postorder_traversal`**: Left subtree → Right subtree → Root. 3. **Example Usage**: - Builds a tree with values `[5, 3, 7, 2, 4, 6, 8]` and demonstrates all three traversal orders. #### Time Complexity Analysis: - **Insert**: O(n) – Worst-case scans all nodes to find insertion position. - **Traversals**: O(n) – Each node is visited exactly once. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值