トピックの説明
实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。
注意:本题相对原题稍作改动
示例:
输入: 1->2->3->4->5 和 k = 2
输出: 4
说明:
给定的 k 保证是有效的。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/kth-node-from-end-of-list-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
問題の解決を開始する (TypeScript)
単一リンクリストで最後から 2 番目の k 番目のノードを見つけるには、ダブル ポインター法を使用してこの問題を解決できます。
まず、高速ポインタと低速ポインタの 2 つのポインタを定義します。最初は、両方のポインタがリンク リストの先頭ノードを指します。
次に、高速ポインタを最初に k ノード前方に移動させます。
次に、高速ポインタがリンク リストの終了ノードを指すまで、高速ポインタと低速ポインタの両方を移動します。
このとき、スローポインタが指すノードは下からk番目のノードとなる。
最後に、スロー ポインターが指すノードの値を返します。
具体的な実装は以下の通りです。
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def findKthFromEnd(head, k):
if not head or k <= 0:
return None
fast = head
for _ in range(k):
if not fast:
return None
fast = fast.next
slow = head
while fast:
fast = fast.next
slow = slow.next
return slow.val
時間計算量分析: ダブル ポインター法では、リンク リストを 1 回走査するだけでよいため、時間計算量は O(n) になります (n はリンク リストの長さ)。
段階的に確認してください
実用化
この関数を使用すると、次のようなリンク リストに関連するいくつかの問題を解決できます。
- リンク リストの k 番目の最後のノードの値を見つける: この
findKthFromEnd(head, k)
関数を呼び出すと、リンク リストの k 番目の最後のノードの値を見つけることができます。これは、下から k 番目のノードの削除、下から k 番目のノードの前のノードの取得など、リンク リストの末尾から操作を開始する必要がある一部のシナリオで非常に役立ちます。 - リンク リストにリングがあるかどうかを判断する: この関数を使用して、リンク リストにリングがあるかどうかを検出できます。リンク リストにリングがある場合、低速ポインタ
slow
と高速ポインタはfast
最終的に出会います。リンク リストにリングがない場合、 この 時点fast
で高速ポインタは最終的にリンク リストの最後に到達します 。fast
null
- リンクされたリストの中間ノードを検索: この関数を使用して、リンクされたリストの中間ノードを検索できます。高速ポインタが
fast
一度に 2 つのノードを移動し、低速ポインタがslow
一度に 1 ノードを移動させることにより、高速ポインタがfast
リンク リストの最後に到達すると、低速ポインタはslow
リンク リストの中間ノードを指すだけになります。 - リンク リストの最後の k 番目のノードを削除する: この関数を使用すると、リンク リスト内の k 番目の最後のノードを見つけて削除できます。削除は、最後から2番目のk番目のノードの前のノードを見つけ、その
next
ポインタが最後から2番目のk番目のノードの次のノードを指すことによって実現できる。 - リンク リストの反転: この機能を使用して、リンク リストの最後から 2 番目のノードを見つけ、それを新しいヘッド ノードとして使用して、リンク リストの反転を実現できます。
これらは関数の実際的な応用例の一部ですが、実際には、この関数を使用してリンク リストに関連するさらに多くの問題を解決できます。