LeetCode:根据给定字符串判断是否为先序二叉树

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 #.
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 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 such as "1,3"

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

Example 2:
Input:"1,#"
Output:false

Example 1:
Input:"9,#,#,1"
Output:false

题目大意:
给定一串以逗号分隔的序列,判断它是否是二叉树的前序序列化.编写一个在不重构树的条件下的可行算法.

解题思路:
如果叶子节点是null,那么所有非null的节点(除了root节点)必定有2个出度,1个入度(2个孩子和1个父亲,孩
子可能为空,但是这一题用"#"表示,则肯定存在有2个孩子),所有的null节点只有0个出度,1个入度(0个孩子和
1个父亲).开始构建这棵数,在构建过程中,记录出度和入度之间的差异:dif=out(出度)-in(入度).当下一个节
点到来时候,将dif-1,因为这个节点提供了一个度.如果这个节点不为null,将dif+2,因为提供了两个出度.若序
列化正确,则dif应该永远不会负,并且dif在完成时将变为0.

验证给定的字符串是否为有效的前缀二叉树序列.
需要用到strtok这是c语言的函数.char*类型,printf这是c的语法,不能简单string输出
c++分割字符串还可以直接枚举也可以.
方法二:
stack的思想.
先序遍历中'#'个数总是比数字个数大1个,而且以#结尾.因此在先序遍历字符串数组中去除最后一个字符'#',
则节点个数与'#'个数应该相匹配.任何时候不能出现'#'个数大于节点的个数.设置count统计个数,在遇到数
字时进行+1,遇到'#'时-1.如果此时小于0则返回false,执行完成后判断最后一个字符是否为'#‘.

C++语言实现

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <vector>
#include <stack>

using namespace std;
class Solution{
public:
    bool isValidSerialization(string preorders){
        /*分割字符串*/
        char *pre=new char[preorders.size()+1];
        strcpy_s(pre,preorders.size()+1,preorders.c_str());/*或者strncpy(pre,orders.c_str(),orders.size()+1)*/
        char* str=strtok(pre,",");
        vector<string> ans;/*或者vector<char>,下面的push_back(*str)*/
        while(str!=nullptr){
            ans.push_back(str);
            str=strtok(NULL,",");
        }
        int dif=1;
        /*入度+2,出度-1*/
        for(auto& c:ans){
            dif--;
            if(dif<0)  return false;
            if(c!="#"){
                dif+=2;
            }
        }
        return dif==0;
    }
    bool isValid(string preorder){
        /*
        vector<string> strs;
        int count=0;
        for(auto& s:preorder){
            in+=s;
            count++;
            if(s==","){
                strs.push_back(in);
                in="";
            }else{
                in+=s;
            }
            if(count==preorder.size()){
                str.push_back(in);//输出最后一个
            }
        }
        */
        stringstream s(preorder);
        vector<string> strs;
        string in;
        while(getline(s,in,'#')){
            strs.emplace_back(in);
        }
        stack<string> res;
        for(auto& str:strs){
            if(str=="#"){
                if(res.empty()){
                    return false;
                }
                res.pop();
            }else{
                res.push(str);
            }
        }
        return strs.back()=="#"&&res.empty();
    }
};

int main(int argc,char* argv[]){
    string preorders="9,#,92,#,#";//"9,3,4,#,#,1,#,#,2,#,6,#,#";
    /*
    string in;
    for(int i=0;i<=preorders.size();++i){
        if(preorders[i]==','||i==preorders.size()){       
            cout<<i<<" "<<in<<endl;
            in="";
        }else{
           in+=preorders[i]; 
        }                  
    }
    */
    //cout<<Solution().isValidSerialization(preorders)<<endl;
    return 0;
}

Go语言实现

package main

import (
	"fmt"
	"strings"
)

func isValidSerialization(preorder string)bool{
	nodes,dif:=strings.Split(preorder,","),1
	for _,node:=range nodes{
		dif--
		if dif<0{
			return false
		}
		if node!="#"{
			dif+=2
		}
	}
	return dif==0
}
func main(){
	preorder:="9,#,92,#,#"//"9,3,4,#,#,1,#,#,2,#,6,#,#"
	fmt.Println(isValidSerialization(preorder))
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上的追梦人

您的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值