我認爲遞歸解決方案工作得很好。在每個節點都可以獲得左右兒童的重量。您有以下情況:
- 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