From a31eb7239597fddef734012efa00f1827dfd636b Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 3 Feb 2024 16:40:26 +0800 Subject: [PATCH] feat: add solutions to lcci problem: No.02.02 No.02.02.Kth Node From End of List --- .../02.02.Kth Node From End of List/README.md | 55 ++++++++++++++++--- .../README_EN.md | 55 ++++++++++++++++--- .../Solution.cpp | 2 +- .../Solution.go | 9 ++- .../Solution.js | 9 ++- .../Solution.py | 3 +- .../Solution.ts | 23 ++++++++ 7 files changed, 130 insertions(+), 26 deletions(-) create mode 100644 lcci/02.02.Kth Node From End of List/Solution.ts diff --git a/lcci/02.02.Kth Node From End of List/README.md b/lcci/02.02.Kth Node From End of List/README.md index 8769f32fc9e14..28b6653c49462 100644 --- a/lcci/02.02.Kth Node From End of List/README.md +++ b/lcci/02.02.Kth Node From End of List/README.md @@ -20,7 +20,11 @@ ## 解法 -### 方法一 +### 方法一:快慢指针 + +我们定义两个指针 `slow` 和 `fast`,初始时都指向链表头节点 `head`。然后 `fast` 指针先向前移动 $k$ 步,然后 `slow` 和 `fast` 指针同时向前移动,直到 `fast` 指针指向链表末尾。此时 `slow` 指针指向的节点就是倒数第 $k$ 个节点。 + +时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。 @@ -38,7 +42,8 @@ class Solution: for _ in range(k): fast = fast.next while fast: - slow, fast = slow.next, fast.next + slow = slow.next + fast = fast.next return slow.val ``` @@ -80,7 +85,7 @@ public: int kthToLast(ListNode* head, int k) { ListNode* fast = head; ListNode* slow = head; - while (k-- > 0) { + while (k--) { fast = fast->next; } while (fast) { @@ -93,9 +98,16 @@ public: ``` ```go +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ func kthToLast(head *ListNode, k int) int { slow, fast := head, head - for i := 0; i < k; i++ { + for ; k > 0; k-- { fast = fast.Next } for fast != nil { @@ -106,6 +118,32 @@ func kthToLast(head *ListNode, k int) int { } ``` +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function kthToLast(head: ListNode | null, k: number): number { + let [slow, fast] = [head, head]; + while (k--) { + fast = fast.next; + } + while (fast !== null) { + slow = slow.next; + fast = fast.next; + } + return slow.val; +} +``` + ```rust // Definition for singly-linked list. // #[derive(PartialEq, Eq, Clone, Debug)] @@ -153,14 +191,13 @@ impl Solution { * @return {number} */ var kthToLast = function (head, k) { - let fast = head, - slow = head; - for (let i = 0; i < k; i++) { + let [slow, fast] = [head, head]; + while (k--) { fast = fast.next; } - while (fast != null) { - fast = fast.next; + while (fast !== null) { slow = slow.next; + fast = fast.next; } return slow.val; }; diff --git a/lcci/02.02.Kth Node From End of List/README_EN.md b/lcci/02.02.Kth Node From End of List/README_EN.md index d9827a0fc8ddb..d994e8cab5f21 100644 --- a/lcci/02.02.Kth Node From End of List/README_EN.md +++ b/lcci/02.02.Kth Node From End of List/README_EN.md @@ -22,7 +22,11 @@ ## Solutions -### Solution 1 +### Solution 1: Two Pointers + +We define two pointers `slow` and `fast`, both initially pointing to the head node `head`. Then the `fast` pointer moves forward $k$ steps first, and then the `slow` and `fast` pointers move forward together until the `fast` pointer points to the end of the list. At this point, the node pointed to by the `slow` pointer is the $k$-th node from the end of the list. + +The time complexity is $O(n)$, where $n$ is the length of the list. The space complexity is $O(1)$. @@ -40,7 +44,8 @@ class Solution: for _ in range(k): fast = fast.next while fast: - slow, fast = slow.next, fast.next + slow = slow.next + fast = fast.next return slow.val ``` @@ -82,7 +87,7 @@ public: int kthToLast(ListNode* head, int k) { ListNode* fast = head; ListNode* slow = head; - while (k-- > 0) { + while (k--) { fast = fast->next; } while (fast) { @@ -95,9 +100,16 @@ public: ``` ```go +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ func kthToLast(head *ListNode, k int) int { slow, fast := head, head - for i := 0; i < k; i++ { + for ; k > 0; k-- { fast = fast.Next } for fast != nil { @@ -108,6 +120,32 @@ func kthToLast(head *ListNode, k int) int { } ``` +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function kthToLast(head: ListNode | null, k: number): number { + let [slow, fast] = [head, head]; + while (k--) { + fast = fast.next; + } + while (fast !== null) { + slow = slow.next; + fast = fast.next; + } + return slow.val; +} +``` + ```rust // Definition for singly-linked list. // #[derive(PartialEq, Eq, Clone, Debug)] @@ -155,14 +193,13 @@ impl Solution { * @return {number} */ var kthToLast = function (head, k) { - let fast = head, - slow = head; - for (let i = 0; i < k; i++) { + let [slow, fast] = [head, head]; + while (k--) { fast = fast.next; } - while (fast != null) { - fast = fast.next; + while (fast !== null) { slow = slow.next; + fast = fast.next; } return slow.val; }; diff --git a/lcci/02.02.Kth Node From End of List/Solution.cpp b/lcci/02.02.Kth Node From End of List/Solution.cpp index e1cfb25771256..9867d88eddcea 100644 --- a/lcci/02.02.Kth Node From End of List/Solution.cpp +++ b/lcci/02.02.Kth Node From End of List/Solution.cpp @@ -11,7 +11,7 @@ class Solution { int kthToLast(ListNode* head, int k) { ListNode* fast = head; ListNode* slow = head; - while (k-- > 0) { + while (k--) { fast = fast->next; } while (fast) { diff --git a/lcci/02.02.Kth Node From End of List/Solution.go b/lcci/02.02.Kth Node From End of List/Solution.go index b4374e09a9a9f..238e9d60e79fa 100644 --- a/lcci/02.02.Kth Node From End of List/Solution.go +++ b/lcci/02.02.Kth Node From End of List/Solution.go @@ -1,6 +1,13 @@ +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ func kthToLast(head *ListNode, k int) int { slow, fast := head, head - for i := 0; i < k; i++ { + for ; k > 0; k-- { fast = fast.Next } for fast != nil { diff --git a/lcci/02.02.Kth Node From End of List/Solution.js b/lcci/02.02.Kth Node From End of List/Solution.js index 8d2465662277a..4d04f84e7e8eb 100644 --- a/lcci/02.02.Kth Node From End of List/Solution.js +++ b/lcci/02.02.Kth Node From End of List/Solution.js @@ -11,14 +11,13 @@ * @return {number} */ var kthToLast = function (head, k) { - let fast = head, - slow = head; - for (let i = 0; i < k; i++) { + let [slow, fast] = [head, head]; + while (k--) { fast = fast.next; } - while (fast != null) { - fast = fast.next; + while (fast !== null) { slow = slow.next; + fast = fast.next; } return slow.val; }; diff --git a/lcci/02.02.Kth Node From End of List/Solution.py b/lcci/02.02.Kth Node From End of List/Solution.py index 94996dad04815..cd1f42b07bb1a 100644 --- a/lcci/02.02.Kth Node From End of List/Solution.py +++ b/lcci/02.02.Kth Node From End of List/Solution.py @@ -11,5 +11,6 @@ def kthToLast(self, head: ListNode, k: int) -> int: for _ in range(k): fast = fast.next while fast: - slow, fast = slow.next, fast.next + slow = slow.next + fast = fast.next return slow.val diff --git a/lcci/02.02.Kth Node From End of List/Solution.ts b/lcci/02.02.Kth Node From End of List/Solution.ts new file mode 100644 index 0000000000000..30ec3d5935e09 --- /dev/null +++ b/lcci/02.02.Kth Node From End of List/Solution.ts @@ -0,0 +1,23 @@ +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function kthToLast(head: ListNode | null, k: number): number { + let [slow, fast] = [head, head]; + while (k--) { + fast = fast.next; + } + while (fast !== null) { + slow = slow.next; + fast = fast.next; + } + return slow.val; +}