Verify Preorder Serialization of a Binary Tree 验证二叉树的前序序列化

序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #

     _9_
    /   \
   3     2
  / \   / \
 4   1  #  6
/ \ / \   / \
# # # #   # #

例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。

给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。

每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 '#' 。

你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。

示例 1:

输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true

示例 2:

输入: "1,#"输出: false

示例 3:

输入: "9,#,#,1"输出: false

思路:这道题的tag虽然是stack,但是没有想出怎么用stack来做,翻了几个discuss的解法,基本都是通过找规律来解答。如果这道题是通过找规律来解,那么就离stack的出题初衷相差甚远。所以目前先给出找规律给出的解答。

观察任何有效的序列,可以发现:

1 所有节点都由出度和入度组成(除了root节点)且"#"比非"#"号多一个。

2如果按照所有节点的出入度来算的话,一个有效的前序序列出入度节点和一定为0。通过这两个条件就可以写出代码,通过一个计数器计算节点的出入度,为了补偿root节点没有入度,所以计数器初始化为-1,每次遍历到一个节点就计数器加一,如果当前节点不是"#"节点,那么再把计数器-2,如果任何时候计数器的值大于0,这就不是一个有效的前序序列,返回false。最后返回计数器的值是否为0。

参考代码:

class Solution {
public:
    bool isValidSerialization(string preorder) {
	istringstream in(preorder);
	string tmp;
	int count = -1;
	while (getline(in, tmp, ',')) {
		count++;
		if (count > 0) return false;
		if (tmp != "#") {
			count -= 2;
		}
	}
	return count == 0;        
    }
};

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Here is an example C++ program that creates a tree node at a specific position in a tree: ```c++ #include <iostream> #include <vector> using namespace std; struct TreeNode { int val; vector<TreeNode*> children; TreeNode(int x) : val(x) {} }; void createNode(TreeNode* root, vector<int> path, int pos, int val) { if (pos == path.size()) { root->children.push_back(new TreeNode(val)); return; } int index = path[pos]; createNode(root->children[index], path, pos + 1, val); } int main() { TreeNode* root = new TreeNode(1); root->children.push_back(new TreeNode(2)); root->children.push_back(new TreeNode(3)); root->children.push_back(new TreeNode(4)); vector<int> path = {1, 0}; // path to the node we want to create int val = 5; // value of the new node createNode(root, path, 0, val); // print the tree to verify the new node was added cout << root->val << endl; for (auto child : root->children) { cout << " " << child->val << endl; for (auto grandchild : child->children) { cout << " " << grandchild->val << endl; } } return 0; } ``` In this program, we define a `TreeNode` struct that represents a node in a tree. Each node has a `val` property representing its value, and a `children` vector representing its children. The `createNode` function takes a `root` parameter representing the root of the tree, a `path` parameter representing the path to the node we want to create (as a vector of indices), a `pos` parameter representing the current position in the path, and a `val` parameter representing the value of the new node. The function recursively traverses the tree along the path until it reaches the position where the new node should be created, and then adds the new node as a child of the current node. In the `main` function, we create a sample tree and then call the `createNode` function to add a new node with value 5 at position [1, 0] (i.e., the second child of the root's first child). We then print the tree to verify that the new node was added correctly.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值