我认为递归解决方案工作得很好。在每个节点都可以获得左右儿童的重量。您有以下情况:
- L和R都知道:该节点是有效的当且仅当大号== [R
- 无论是L或R是已知的:该节点是未知的,具有多重 两倍的L和R的最大重数
- L或R中的一个是未知数:如果已知子的权重可由 未知子的整数倍整除,则此节点有效。它的体重是已知孩子体重的两倍。
这里的想法是,你需要跟踪有多少未知的孩子在某个节点下面,因为值只能是整数。多重性总是双倍的,因为在一个节点上,即使其左边的孩子有4个未知数,其右边有1个未知数,那么1个未知数必须是4的倍数,因此这个节点的多重性将需要为8。
注意:我在这里使用了多重性这个词,它并不是非常正确,但我想不出一个好用的词。
这里是代码,在去,证明你的例子此解决方案:
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)
}
你总是可以尝试绘制树在一个代码块:| – Alexander 2012-07-21 21:38:36
不会创建一个大的方程组,而是创建小的方程组,解决它们,然后填充结果并搜索下一个子问题。 – 2012-07-21 23:50:03