Pythonで連結リストの隣接ノード間の絶対差が1かどうかを判定する方法
整数値を格納したノードからなる単方向連結リストが与えられたとき、隣り合うノード同士の値の絶対差がすべて「1」になっているかどうかを判定する問題を考えてみましょう。
たとえば、入力が 5 → 6 → 7 → 8 → 7 → 6 → 5 → 4 のような連結リストだった場合、どの隣接ノード間でも差が1なので、出力は True になります。
解法のアプローチ
この問題は、リストを先頭から順に走査しながら、隣接する2つのノードの値を比較していくことで解決できます。手順は以下の通りです。
- 一時変数
tempに先頭ノード(start_node)を代入する tempが null でない限り、以下を繰り返すtemp.linkが null(最後のノード)なら、ループを抜ける- |temp の値 − temp.link の値| が 1 でなければ、
Falseを返す tempを次のノードに進める
- 最後まで条件を満たしていれば、
Trueを返す
このアルゴリズムの計算量は O(n)、必要な追加メモリは O(1) であり、リストの長さに対して線形時間で効率的に動作します。
Pythonでの実装例
それでは、実際のコードを見てみましょう。
class link_node:
def __init__(self, value):
self.value = value
self.link = None
def make_list(elements):
head = link_node(elements[0])
ptr = head
for element in elements[1:]:
ptr.link = link_node(element)
ptr = ptr.link
return head
def solve(start_node):
temp = start_node
while temp:
# 最後のノードに到達したら終了
if temp.link is None:
break
# 隣接ノードの絶対差が1でなければ False
if abs(temp.value - temp.link.value) != 1:
return False
temp = temp.link
return True
start_node = make_list([5, 6, 7, 8, 7, 6, 5, 4])
print(solve(start_node))コードのポイント
link_nodeクラスは、値(value)と次ノードへの参照(link)を持つシンプルなノード定義です。make_list関数は、要素のリストを受け取って連結リストを構築します。末尾への追加を O(1) で行うため、ポインタptrを使い回しています。solve関数が本体の判定処理です。abs()を使って絶対差を計算し、1以外なら即座にFalseを返します。
実行結果
入力
[5, 6, 7, 8, 7, 6, 5, 4]
出力
True
このように、リスト内のすべての隣接ノードの絶対差が1であるため、True が出力されます。もし途中で差が1以外になるノードが存在すれば(例: [1, 2, 5] のような場合)、その時点で False が返されます。
-
Python – リスト内の要素を連続的に除算する方法
Pythonでリスト内の要素を連続的に除算する(最初の要素から始めて、残りの要素で順番に割っていく)必要がある場合があります。そのようなときは、リストの要素を反復処理し、「/」演算子を使って結果を求める関数を定義すると簡単に実現できます。 以下に具体的な実装例を示します。 サンプルコード def consec_division(my_list): my_result = my_list[0] for idx in range(1, len(my_list)): my_result /= my_list[idx] return my_result m
-
Pythonで連結リストのm個のノードを保持した後にn個のノードを削除するプログラム
始点ノードが「head」である連結リストと、2つの整数 m と n が与えられたとします。リストを走査しながら、先頭から数えて m 個のノードを残した直後の n 個のノードを削除する処理を、連結リストの末尾に到達するまで繰り返します。処理は head ノードから開始し、最後に変更後の連結リストを返します。今回扱う連結リストの構造は次のように定義されています。Node value : <整数値> next : <次のノードへのポインタ>例えば、入力が elements = [1, 2, 3, 4, 5, 6, 7, 8]、m = 3、n = 1 の場合、出