我认为递归解决方案工作得很好。在每个节点获得左右孩子的权重。您有以下情况:
- L 和 R 都是已知的:节点有效当且仅当 L == R
- L 或 R 都不知道:这个节点是未知的,其多重性是 L 和 R 的最大多重性的两倍
- L 或 R 中的一个是未知的:如果已知子节点的权重可被未知子节点的倍数整除,则此节点有效。它的重量是已知孩子体重的两倍。
这里的想法是您需要跟踪某个节点下方有多少未知子节点,因为值只能是整数。多重性总是加倍,因为在一个节点上,即使它的左孩子有 4 个未知数,而它的右边有 1 个未知数,那么 1 未知数必须是 4 的倍数,所以这个节点的多重性必须是 8。
注意:我在这里使用了多重性这个词,它并不完全正确,但我想不出一个好的词来使用。
这是 Go 中的代码,用于在您的示例中演示此解决方案:
package main
import (
"fmt"
)
// Assume that (Left == nil) == (Right == nil)
type Tree struct {
Val int
Left, Right *Tree
}
func (t *Tree) GetWeight() (weight int, valid bool) {
if t.Left == nil {
return t.Val, true
}
l, lv := t.Left.GetWeight()
r, rv := t.Right.GetWeight()
if !lv || !rv {
return 0, false
}
if l < 0 && r < 0 {
if l < r {
return 2 * l, true
}
return 2 * r, true
}
if l < 0 {
return 2 * r, r%(-l) == 0
}
if r < 0 {
return 2 * l, l%(-r) == 0
}
return r + l, r == l
}
func main() {
t := Tree{0,
&Tree{0,
&Tree{0,
&Tree{Val: 5},
&Tree{Val: -1},
},
&Tree{Val: 10},
},
&Tree{0,
&Tree{Val: -1},
&Tree{Val: -1},
},
}
w, v := t.GetWeight()
fmt.Printf("%d, %t\n", w, v)
t = Tree{0,
&Tree{0,
&Tree{0,
&Tree{Val: -1},
&Tree{Val: -1},
},
&Tree{Val: 5},
},
&Tree{Val: -1},
}
w, v = t.GetWeight()
fmt.Printf("%d, %t\n", w, v)
}