LeetCode题解——Verify Preorder Serialization of a Binary Tree

题目:

One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #.

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

For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node.

Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree.

Each comma separated value in the string must be either an integer or a character '#' representing null pointer.

You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3".

Example 1:
"9,3,4,#,#,1,#,#,2,#,6,#,#"
Return true

Example 2:
"1,#"
Return false

Example 3:
"9,#,#,1"
Return false

解题思路:

当连续遇到两个‘#’字符时,可以认为找到了一个叶节点,那么可以用一个‘#’来代替 a,'#','#' 对这棵树的结果不会有影响。

分析如下:

"9,3,4,#,#,1,#,#,2,#,6,#,#" 求解过程如下:

9,3,4,#,# ——> 9,3,#

9,3,#,1,#,# ——>9,3,#,# ——>9,#

9,#,2,#,6,#,# ——>9,#,2,#,# ——>9,#,# ——> #

当最后只剩下一个字符‘#’时,认为该字符串是二叉树的前序遍历结果。

class Solution {
public:
bool isValidSerialization(string p) {
    //如何serialization the tree and deserialize the code?
    stack<string> s;
    while(p.size()!=0){
		int pos = p.find(',');
		string t = p.substr(0,pos);
		p = p.substr(pos+1);

		if(pos==-1){
			t = p;
			p = "";
		}
		
		string pre = "";
		if(!s.empty()) pre = s.top();
		s.push(t);
		while( pre =="#" && s.top()=="#"){
			s.pop();
			s.pop();
			if(!s.empty() && s.top()!="#"){
				s.pop();
				if(!s.empty()) pre = s.top();
				else pre = "";
				s.push("#");
			}
			else{
				s.push("#");
				s.push("#");
				pre = "";
			}
		}
    }
	return s.size()==1 && s.top()=="#";   
}
};

第二种想法:考虑树的节点的性质:树的叶节点数 = 树的非叶结点树+1;并且在前序遍历的过程中叶节点树不可能大于非叶结点数。因为最后遍历的一个数为叶节点,所以之前的遍历中,叶节点数<= 非叶结点数

class Solution {
public:
    bool isValidSerialization(string preorder) {
        istringstream s(preorder);
        int node_c = 0, null_c = 0;
        string cur;
        while (getline(s, cur, ',')) {
            if (cur == "#") ++null_c;
            else ++node_c;
            if (s.good() && null_c == node_c + 1) return false;
        }
        return null_c == node_c + 1;
    }
};


序列化二叉树和反序列化二叉树程序:

#include <stdio.h>
#include "..\Utilities\BinaryTree.h"
#include <iostream>
#include <fstream>

using namespace std;

void Serialize(BinaryTreeNode* pRoot, ostream& stream)
{
    if(pRoot == NULL)
    {
        stream << "$,";
        return;
    }
    
    stream << pRoot->m_nValue << ',';
    Serialize(pRoot->m_pLeft, stream);
    Serialize(pRoot->m_pRight, stream);
}

bool ReadStream(istream& stream, int* number)
{
    if(stream.eof())
        return false;
    
    char buffer[32];
    buffer[0] = '\0';
    
    char ch;
    stream >> ch;
    int i = 0;
    while(!stream.eof() && ch != ',')
    {
        buffer[i++] = ch;
        stream >> ch;
    }
    
    bool isNumeric = false;
    if(i > 0 && buffer[0] != '$')
    {
        *number = atoi(buffer);
        isNumeric = true;
    }
        
    return isNumeric;
}

void Deserialize(BinaryTreeNode** pRoot, istream& stream)
{
    int number;
    if(ReadStream(stream, &number))
    {
        *pRoot = new BinaryTreeNode();
        (*pRoot)->m_nValue = number;
        (*pRoot)->m_pLeft = NULL;
        (*pRoot)->m_pRight = NULL;

        Deserialize(&((*pRoot)->m_pLeft), stream);
        Deserialize(&((*pRoot)->m_pRight), stream);
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值