ヒープも優先キューとして知られているが、抽象データ型です。概念的には、すべてのノードの子がノード自体以下であるバイナリツリーです。(最大ヒープと仮定します。)要素がプッシュまたはポップされると、ヒープはそれ自体を再配置し、最大の要素が次にポップされるようにします。ツリーまたは配列として簡単に実装できます。
受け入れを選択した場合の課題は、アレイが有効なヒープかどうかを判断することです。すべての要素の子が要素自体以下の場合、配列はヒープ形式になります。例として次の配列を取り上げます。
[90, 15, 10, 7, 12, 2]
本当に、これは配列の形に配置された二分木です。これは、すべての要素に子があるためです。90には、15と10の2つの子があります。
15, 10,
[(90), 7, 12, 2]
15には子もあり、7と12:
7, 12,
[90, (15), 10, 2]
10には子供がいます:
2
[90, 15, (10), 7, 12, ]
次の要素も10の子になりますが、スペースがないことを除きます。配列が十分に長ければ、7、12、および2にもすべて子があります。ヒープの別の例を次に示します。
[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]
そして、これは前の配列が作るツリーの視覚化です:
これが十分に明確でない場合に備えて、i番目の要素の子を取得するための明示的な式を次に示します
//0-indexing:
child1 = (i * 2) + 1
child2 = (i * 2) + 2
//1-indexing:
child1 = (i * 2)
child2 = (i * 2) + 1
空でない配列を入力として受け取り、配列がヒープ順であれば真の値を出力し、そうでなければ偽の値を出力する必要があります。これは、プログラム/関数が予期する形式を指定する限り、0インデックス付きヒープ、または1インデックス付きヒープになります。すべての配列に正の整数のみが含まれると想定できます。ヒープ組み込みは使用できません。これには以下が含まれますが、これらに限定されません
- 配列がヒープ形式かどうかを判断する関数
- 配列をヒープまたはヒープ形式に変換する関数
- 入力として配列を受け取り、ヒープデータ構造を返す関数
このpythonスクリプトを使用して、配列がヒープ形式であるかどうか(0インデックス)を確認できます。
def is_heap(l):
for head in range(0, len(l)):
c1, c2 = head * 2 + 1, head * 2 + 2
if c1 < len(l) and l[head] < l[c1]:
return False
if c2 < len(l) and l[head] < l[c2]:
return False
return True
テストIO:
これらの入力はすべてTrueを返す必要があります。
[90, 15, 10, 7, 12, 2]
[93, 15, 87, 7, 15, 5]
[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[100, 19, 36, 17, 3, 25, 1, 2, 7]
[5, 5, 5, 5, 5, 5, 5, 5]
そして、これらの入力はすべてFalseを返す必要があります。
[4, 5, 5, 5, 5, 5, 5, 5]
[90, 15, 10, 7, 12, 11]
[1, 2, 3, 4, 5]
[4, 8, 15, 16, 23, 42]
[2, 1, 3]
いつものように、これはコードゴルフなので、標準的な抜け穴が適用され、バイト単位の最短回答が勝ちます!
[3, 2, 1, 1]
ですか?