331.验证二叉树的前序序列化

一、题目描述

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

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

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

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

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

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

示例 1:

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

示例 2:

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

示例 3:

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

二、题解

1.算法描述

  • 栈、字符串切割

2.个人分析

  1. 将字符串以,切割
  2. 将子字符串逐一进栈
  3. 当栈顶元素与次栈顶元素都为#时,连出三次栈,并将#压入栈中
  4. 在遍历字符串的过程中,如果栈恰好为空,且子字符串为空时,说明符合要求,返回true;
  5. 在遍历字符串的过程中,如果栈恰好为空,且子字符串不为空时,说明不符合要求,返回false;

3.代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#define maxSize 1024
typedef struct stack
{
char *data[maxSize];
int top;
} stack;

bool isValidSerialization(char *preorder)
{
if (preorder[0] == '#' && preorder[1] == '\0')
return true;
if (preorder[0] == '#' && preorder[1] != '\0')
return false;
//初始化
stack *st = (stack *)malloc(sizeof(stack));
int i;
for (i = 0; i < maxSize; i++)
st->data[i] = NULL;
st->top = -1;
//切割字符串
char *str = preorder;
char delim[2] = ",";
char *token = NULL;
token = strtok(str, delim);
//入栈
char ship[2] = "#";
while (token != NULL)
{
st->data[++st->top] = token;
token = strtok(NULL, delim);
while (st->data[st->top][0] == '#' && st->data[st->top - 1][0] == '#')
{
st->data[st->top--] = NULL;
st->data[st->top--] = NULL;
st->data[st->top--] = NULL;
if (st->top == -1 && token != NULL)
return false;
if (st->top == -1 && token == NULL)
return true;
st->data[++st->top] = ship;
}
}
return false;
}