Pythonで連結リストの後ろからK番目のノードを見つけるプログラム
問題概要
片方向連結リストが与えられたとき、後ろからk番目のノード(0始まりのインデックス)の値を求めることを考えます。ただし、この問題はリストを1回の走査(シングルパス)で解く必要があります。
例えば、入力が node = [5,4,6,3,4,7]、k = 2 の場合、出力は 3 になります。これは、後ろから2番目(インデックス3)のノードの値が3であるためです。
解法のアプローチ:2ポインタ技法
この問題を効率的に解くには、2つのポインタを使う手法が有効です。片方のポインタを先にkステップだけ進めておき、その後両方のポインタを同時に末尾へ向けて進めます。先頭のポインタが末尾に到達したとき、もう片方のポインタが指しているのが後ろからk番目のノードです。
具体的には、以下の手順に従います。
klastをnode(先頭ノード)に設定します。lastもnode(先頭ノード)に設定します。i が 0 から k までの間、以下を繰り返します。
lastを次のノードに進めます。
lastの次のノードが存在する間、以下を繰り返します。lastを次のノードに進めます。klastも次のノードに進めます。
klastの値を返します。
このアルゴリズムの計算量は時間 O(n)、空間 O(1) であり、リスト全体を事前に走査して長さを求める必要がないため、1回のパスで目的のノードに到達できます。
実装例
理解を深めるために、以下のPythonコードを見てみましょう。
class ListNode:
def __init__(self, data, next = None):
self.val = data
self.next = next
def make_list(elements):
head = ListNode(elements[0])
for element in elements[1:]:
ptr = head
while ptr.next:
ptr = ptr.next
ptr.next = ListNode(element)
return head
class Solution:
def solve(self, node, k):
klast = node
last = node
for i in range(k):
last = last.next
while last.next:
last = last.next
klast = klast.next
return klast.val
ob = Solution()
l1 = make_list([5,4,6,3,4,7])
print(ob.solve(l1, 2))
入力
[5,4,6,3,4,7], 2
出力
3
まとめ
このように、2つのポインタの距離をkだけ保ちながら同時に進めることで、連結リストの長さを事前に知らなくても、後ろからk番目のノードの値を1回の走査だけで取得できます。面接やコーディングテストで頻出のテクニックなので、ぜひ覚えておきましょう。
-
Pythonでリスト内の最小値を見つける方法を解説
この記事では、リストの中から最小の数値を見つける方法について、具体的なサンプルコードとともに詳しく解説します。問題の概要問題: 数値のリストが与えられたとき、その中に含まれる最も小さい数値を画面に表示すること。この問題を解くアプローチは主に2つあります。ひとつは sort() メソッドを使ってリストを昇順に並べ替え、先頭の要素(インデックス0)を取得する方法。もうひとつは、Pythonに標準で用意されている組み込み関数 min() を使う方法です。それぞれ順番に見ていきましょう。方法1:sort()メソッドで並べ替えて最小値を取得するまずはリストを昇順にソートし、先頭の要素を取り出す方法です。
-
Pythonでリスト内の最大値を見つける方法をわかりやすく解説
この記事では、Pythonを使ってリストの中から最大の要素(最大値)を見つける方法について解説します。初心者の方でも理解しやすいよう、複数のアプローチをコード例とともに紹介していきます。 問題の概要 問題文: 与えられたリストの中から、最も大きい要素を求めて出力してください。 Pythonには便利な組み込み関数が用意されているため、これらを活用することで短いコードで効率的に問題を解決できます。ここでは主に sort() メソッドと max() 関数の2つの方法を取り上げます。 方法1:sort() 関数を使う sort() メソッドはリストを昇順に並べ替えます。並べ替え後のリストの末尾(インデ