缩点法验证二叉树的前序序列化
- 题目
- 解决思路
- 代码
- 说明
题目
(1)序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
(2)如下为一棵二叉树:
(3)例如,上面的二叉树可以被序列化为字符串 “9,3,4,#,#,1,#,#,2,#,6,#,#”,其中 # 代表一个空节点。
(4)给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
(5)每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 ‘#’ 。
(6)你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 “1,3” 。
解决思路
- 题意解析:题意即判断输入的字符串是否为一颗二叉树的前序遍历序列。
- 思路:解题核心是进行缩点,即将3个点压缩为1个点。若一个字符串最终能缩成一个点,且该点的值为“#”,则给定的字符串是一棵二叉树的前序遍历序列。
- 具体步骤如下:
代码
- C++代码
# include <stdio.h>
# include <string>
# include <vector>using namespace std;class Solution {
public:bool isValidSerialization(string preorder) {vector<string> tmp; // 用数组模拟栈,保存去掉逗号后的字符串。// 遍历字符串,并用 j 记录逗号的下标。for (int i = 0, j = 0; i < preorder.size(); i = j + 1) {j = i;while (j < preorder.size() && ',' != preorder[j]) {j++;}// 去除逗号,根据逗号的位置截取子串。tmp.push_back(preorder.substr(i, j - i));// 进行缩点,将3个点缩为1个点,如可以将4,#,#缩为一个#。则将3个点缩为了1个点。int last = tmp.size() - 1;while (tmp.size() >= 3 && "#" == tmp[last] && "#" == tmp[last - 1] && "#" != tmp[last - 2]) {tmp[last - 2] = "#";tmp.pop_back(); // 去掉tmp[last]位置的“#”tmp.pop_back(); // 去掉s[last-1]位置的“#”last = tmp.size() - 1;}}// 当最后栈中只有一个元素,且该元素为“#”时,说明原字符串是一个二叉树前序序列。return 1 == tmp.size() && "#" == tmp[0];}
};int main() {string preorder = "9,3,4,#,#,1,#,#,2,#,6,#,#";Solution *solution = new Solution();printf("%d\n", solution->isValidSerialization(preorder));return 0;
}
- Python代码
# -*- coding: utf-8 -*-from typing import Listclass Solution:def __init__(self):passdef isValidSerialization(self, preorder: str) -> bool:tmp: List[str] = [] # 用数组模拟栈,保存去掉逗号后的字符串。preorder = preorder.split(',') # 使用逗号进行分割for s in preorder:tmp.append(s)# 进行缩点,将3个点缩为1个点,如可以将4,#,#缩为一个#。则将3个点缩为了1个点。while len(tmp) >= 3 and "#" == tmp[-1] and "#" == tmp[-2] and "#" != tmp[-3]:tmp[-3] = "#"tmp.pop() # 去掉tmp[-1]位置的“#”tmp.pop() # 去掉s[-2]位置的“#”# 当最后栈中只有一个元素,且该元素为“#”时,说明原字符串是一个二叉树前序序列。return 1 == len(tmp) and "#" == tmp[0]def main():solution = Solution()preorder: str = "9,3,4,#,#,1,#,#,2,#,6,#,#"print(solution.isValidSerialization(preorder))if __name__ == "__main__":main()
说明
- 对应LeetCode第331题。
- 链接:https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree/