インタージェイは、あなたの答えが間違っている理由を指摘しました。find-max-independent
この問題は、二分木が与えられた場合に2つのケースを考慮する再帰的アルゴリズムで解決できます。
- ルートノードが含まれている場合、最大独立集合とは何ですか?
- ルートノードが含まれていない場合、最大独立集合とは何ですか?
ケース1では、ルートノードが含まれているため、その子はどちらも含まれていません。したがってfind-max-independent
、rootの孫の値とrootの値(含まれている必要があります)を合計し、それを返します。
ケース2では、子ノードの最大値がfind-max-independent
あればそれを返します(1つしか選択できません)
アルゴリズムは次のようになります(Pythonの場合)。
def find_max_independent ( A ):
N=len(A)
def children ( i ):
for n in (2*i+1, 2*i+2):
if n<N: yield n
def gchildren ( i ):
for child in children(i):
for gchild in children(child):
yield gchild
memo=[None]*N
def rec ( root ):
"finds max independent set in subtree tree rooted at root. memoizes results"
assert(root<N)
if memo[root] != None:
return memo[root]
# option 'root not included': find the child with the max independent subset value
without_root = sum(rec(child) for child in children(root))
# option 'root included': possibly pick the root
# and the sum of the max value for the grandchildren
with_root = max(0, A[root]) + sum(rec(gchild) for gchild in gchildren(root))
val=max(with_root, without_root)
assert(val>=0)
memo[root]=val
return val
return rec(0) if N>0 else 0
いくつかのテストケースを示します。
tests=[
[[1,2,3,4,5,6], 16], #1
[[-100,2,3,4,5,6], 6], #2
[[1,200,3,4,5,6], 200], #3
[[1,2,3,-4,5,-6], 6], #4
[[], 0],
[[-1], 0],
]
for A, expected in tests:
actual=find_max_independent(A)
print("test: {}, expected: {}, actual: {} ({})".format(A, expected, actual, expected==actual))
サンプル出力:
test: [1, 2, 3, 4, 5, 6], expected: 16, actual: 16 (True)
test: [-100, 2, 3, 4, 5, 6], expected: 15, actual: 15 (True)
test: [1, 200, 3, 4, 5, 6], expected: 206, actual: 206 (True)
test: [1, 2, 3, -4, 5, -6], expected: 8, actual: 8 (True)
test: [], expected: 0, actual: 0 (True)
test: [-1], expected: 0, actual: 0 (True)
テストケース1

テストケース2

テストケース3

テストケース4

メモ化されたアルゴリズムの複雑さは、O(n)
ノードrec(n)
ごとに1回呼び出されるためです。これは、深さ優先探索を使用したトップダウンの動的計画法ソリューションです。
(テストケースの図は、leetcodeのインタラクティブなバイナリツリーエディタの厚意により提供されています)