Skip to content

Commit 9cadc0e

Browse files
committed
leetcode 19. Remove Nth Node From End of List Two Pointers
1 parent 97928fd commit 9cadc0e

4 files changed

Lines changed: 566 additions & 0 deletions

File tree

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
**removeNthFromEnd関数**」の処理について、
2+
**図解+具体的な解析**を行います。
3+
4+
---
5+
6+
# 🎯 **問題再確認**
7+
8+
**リンクリストの末尾から n 番目のノードを削除せよ。**
9+
10+
例:
11+
`head = [1,2,3,4,5], n=2`
12+
**「4」を削除する**
13+
14+
---
15+
16+
# 🚀 **アルゴリズム概要**
17+
18+
## **ダミーノード作成**
19+
20+
ダミーノード(dummy)を使うことで、
21+
**先頭ノードを削除する場合も安全に処理**できます。
22+
23+
```
24+
初期リスト: [1] -> [2] -> [3] -> [4] -> [5]
25+
26+
ダミーノード追加後:
27+
[0(dummy)] -> [1] -> [2] -> [3] -> [4] -> [5]
28+
```
29+
30+
---
31+
32+
## **fast ポインタを n+1 進める**
33+
34+
`fast`ポインタを「n+1回」進めます。
35+
(これにより `slow` の位置が削除対象の直前になる)
36+
37+
### 図:`n=2` の場合
38+
39+
```
40+
dummy -> 1 -> 2 -> 3 -> 4 -> 5
41+
42+
fast : 初期位置(dummy)
43+
44+
進める操作:
45+
fast = fast.next (3回繰り返し)
46+
47+
1回目: fast → 1
48+
2回目: fast → 2
49+
3回目: fast → 3
50+
```
51+
52+
---
53+
54+
## **fast と slow を同時に進める**
55+
56+
fastが末尾(null)になるまで、`fast``slow` を同時に動かします。
57+
58+
| ステップ | fast の位置 | slow の位置 |
59+
| ---- | -------- | -------- |
60+
| 初期 | 3 | dummy |
61+
| 1回目 | 4 | 1 |
62+
| 2回目 | 5 | 2 |
63+
| 3回目 | null | 3 |
64+
65+
### 図:
66+
67+
```
68+
dummy -> 1 -> 2 -> 3 -> 4 -> 5
69+
70+
slow
71+
```
72+
73+
---
74+
75+
## **削除対象のノードをスキップ**
76+
77+
`slow.next = slow.next.next` にすることで、
78+
**4番目のノード(4)を削除**
79+
80+
### 図:
81+
82+
```
83+
変更前:
84+
3 -> 4 -> 5
85+
86+
変更後:
87+
3 -> 5
88+
```
89+
90+
---
91+
92+
## **結果リスト**
93+
94+
```
95+
dummy -> 1 -> 2 -> 3 -> 5
96+
97+
=> [1] -> [2] -> [3] -> [5]
98+
```
99+
100+
---
101+
102+
# 🧠 **処理全体まとめ(図解)**
103+
104+
```
105+
[0(dummy)] -> [1] -> [2] -> [3] -> [4] -> [5]
106+
↑ ↑
107+
slow fast ← n+1個進めた状態
108+
109+
移動:
110+
fastとslowを同時に動かす
111+
112+
最終状態:
113+
[0(dummy)] -> [1] -> [2] -> [3] -> [4] -> [5]
114+
↑ ↑
115+
slow fast (null)
116+
117+
削除処理:
118+
slow.next = slow.next.next
119+
120+
結果:
121+
[0(dummy)] -> [1] -> [2] -> [3] -> [5]
122+
123+
返却値:
124+
dummy.next = [1] -> [2] -> [3] -> [5]
125+
```
126+
127+
---
128+
129+
# 🕒 **計算量**
130+
131+
* **時間計算量:**
132+
O(sz) (fastポインタとslowポインタをそれぞれ1回走査)
133+
134+
* **空間計算量:**
135+
O(1) (ポインタのみ使用)
136+
137+
---
138+
139+
# 💡 **この方法のメリット**
140+
141+
* **1パスで解ける(2回走査不要)**
142+
* ダミーノードを使うことで「先頭要素削除」にも対応可能
143+
* シンプルで実用的なテクニック(2ポインター法)
144+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// 以下は、**JavaScript(Node.js 18.16.1)** を使った LeetCode形式の「**Remove Nth Node From End of List**」問題の解法です。
2+
3+
// ### アプローチ:
4+
5+
// * **二重ポインター法(fast & slow)**
6+
// 1回のリスト走査で削除可能
7+
// **時間計算量:** O(sz)
8+
// **空間計算量:** O(1)
9+
10+
// ---
11+
12+
// ## 実装
13+
14+
// ```javascript
15+
/**
16+
* Definition for singly-linked list.
17+
* function ListNode(val, next) {
18+
* this.val = (val===undefined ? 0 : val)
19+
* this.next = (next===undefined ? null : next)
20+
* }
21+
*/
22+
23+
/**
24+
* 指定されたリンクリストの末尾から n 番目のノードを削除し、リストの先頭を返す
25+
*
26+
* @param {ListNode} head - リンクリストの先頭ノード
27+
* @param {number} n - 末尾から数えた削除対象ノードの位置
28+
* @returns {ListNode} - 削除後のリンクリストの先頭
29+
*
30+
* 時間計算量: O(sz)
31+
* メモリ消費量: O(1)(追加のメモリは定数)
32+
*/
33+
function removeNthFromEndJs(head, n) {
34+
// ダミーノードを作成(head削除時も対応可能にする)
35+
const dummy = new ListNode(0, head);
36+
37+
let fast = dummy;
38+
let slow = dummy;
39+
40+
// fastポインターをn+1個先に進める
41+
for (let i = 0; i <= n; i++) {
42+
fast = fast.next;
43+
}
44+
45+
// fastとslowを同時に進める
46+
while (fast !== null) {
47+
fast = fast.next;
48+
slow = slow.next;
49+
}
50+
51+
// slow.nextが削除対象
52+
slow.next = slow.next.next;
53+
54+
return dummy.next;
55+
}
56+
57+
// ## 解説
58+
59+
// ### 具体例(図解)
60+
61+
// 例: `head = [1,2,3,4,5], n = 2`
62+
63+
// ```
64+
// ダミーノード: 0 -> 1 -> 2 -> 3 -> 4 -> 5
65+
66+
// 1. fastをn+1=3回進める(fastは「3」を指す)
67+
// 2. fastとslowを同時に進める
68+
69+
// fast: 4 slow: 1
70+
// fast: 5 slow: 2
71+
// fast: null slow: 3
72+
73+
// 3. slow.next (4) を削除:
74+
// 3 -> 5 にする
75+
76+
// 最終結果: 1 -> 2 -> 3 -> 5
77+
// ```
78+
79+
// ---
80+
81+
// ## **時間・メモリの評価**
82+
83+
// * **時間計算量:** O(sz)(リンクリスト1回走査)
84+
// * **空間計算量:** O(1)(ポインターのみ使用)
85+
86+
// ---
87+
88+
// ## **備考**
89+
90+
// * `ListNode` クラスは LeetCode 環境で自動的に定義されています。
91+
// * この実装は、`head` が削除対象の場合も安全に動作します(ダミーノード利用)。
92+

0 commit comments

Comments
 (0)