【二分木】二分木の事前注文シリアル化を確認する

0x00トピック

二分木をシリアル化する1つの方法前序遍历
は、非空ノードに遭遇したときにこのノードの値を記録する
ことです。ノードの場合は、タグを使用して値を記録できます。#

逗号区切ら、それがのバイナリツリーのシリアル化である
ことを確認し、ツリー再構築ます。正确前序

カンマで区切られた各文字は、整数
またはポインタを表すnullポインタです。#
入力形式は常に有効であると考えることができます
。たとえば、次のように2つの連続したカンマが含まれることはありません。1,,3


0x01のアイデア

方法1:

最初にと呼ばれる概念を定義します槽位

A槽位は、現在のバイナリツリーで待機して被节点填充いる位置と見なすことができます。

二分木の確立には、槽位数。ノードに遭遇したときはいつでも:
a。ノード消耗スロットが必要です
b。非空ノード消耗1つのスロットに加えて、さらに补充2つのスロットが必要です

スタックを使用してスロットの変更を維持し
ます。各元素スタックは対応するノードの残りのスロットを表し、スタック数量
の一番上の要素は次のステップで使用可能なスロットの数に対応します。

ノードが検出されると、スタックの最上位要素のみがデクリメントされます。ノード1
が検出されると、スタックの最上位要素がデクリメントされ、1つがスタックにプッシュされます。非空12

スタックの一番上の要素がになるときはいつでも、スタックの一番上をトラバース0した直後に、スタックが埋められるスロットがないことを示している場合、それはシーケンスです弹出
为空
合法

それ以外の場合、スタック不为空を使用するとシーケンスが無効になります
。また、トラバースの過程でスロット数を使用不足するとシーケンスが無効になります。


方法2:计数

方法1のスペースの複雑さを最適化O(1)できますか?
方法1のロジックを振り返ると、スタック内の要素が1つ整体
、つまり数量、スロットも維持できます。变化

したがって、1つだけが維持され计数器ます。つまり、スタック内のすべての要素の
残り変更されないままになります。


0x02ソリューション

言語:Swift

解決策1:

func isValidSerialization(_ preorder: String) -> Bool {
    let n = preorder.count
    var i = 0
    var stack: [Int] = [1]
    
    while i < n {
    	// 槽位数量不足
        if stack.isEmpty {
            return false
        }
        
        // 取一个字符
        let sIndex = preorder.startIndex
        var index = preorder.index(sIndex, offsetBy: i)
        let c = preorder[index]
        
        // 判断字符
        if c == "," {
            i += 1
        }else if c == "#" {
        	// 空节点
            let last = stack.last! - 1
            if last == 0 {
                stack.removeLast()
            }else{
                stack[stack.count-1] = last
            }
            i += 1
        }else{
            // 读一个数字
            var s = Character("c")
            while i < n && s != "," {
                index = preorder.index(sIndex, offsetBy: i)
                s = preorder[index]
                i += 1
            }
            
            let last = stack.last! - 1
            if last == 0 {
                stack.removeLast()
            }else{
                stack[stack.count-1] = last
            }
            stack.append(2)
        }
    }
    return stack.isEmpty
}

解決策2:

func isValidSerializationV2(_ preorder: String) -> Bool {
    let n = preorder.count
    var i = 0
    var slots = 1
    
    while i < n {
        if slots == 0 {
            return false
        }
        
        let sIndex = preorder.startIndex
        var index = preorder.index(sIndex, offsetBy: i)
        let c = preorder[index]
        
        if c == "," {
            i += 1
        }else if c == "#" {
            slots -= 1
            i += 1
        }else{
            // 读一个数字
            var s = Character("c")
            while i < n && s != "," {
                index = preorder.index(sIndex, offsetBy: i)
                s = preorder[index]
                i += 1
            }
            slots += 1 // slots = slots - 1 + 2
        }
    }
    return slots == 0
}


スモールノートアプリケーション

画像の説明を追加してください


おすすめ

転載: blog.csdn.net/xjh093/article/details/123130354