From affc729ad477b50c71ca1c00276ad4753341419c Mon Sep 17 00:00:00 2001 From: yanglbme Date: Thu, 25 Jul 2024 16:48:57 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.0725 No.0725.Split Linked List in Parts --- .../0725.Split Linked List in Parts/README.md | 200 ++++++++++++++---- .../README_EN.md | 200 ++++++++++++++---- .../Solution.cpp | 33 +++ .../Solution.go | 34 +++ .../Solution.java | 40 ++-- .../Solution.py | 39 ++-- .../Solution.ts | 33 +++ 7 files changed, 456 insertions(+), 123 deletions(-) create mode 100644 solution/0700-0799/0725.Split Linked List in Parts/Solution.cpp create mode 100644 solution/0700-0799/0725.Split Linked List in Parts/Solution.go create mode 100644 solution/0700-0799/0725.Split Linked List in Parts/Solution.ts diff --git a/solution/0700-0799/0725.Split Linked List in Parts/README.md b/solution/0700-0799/0725.Split Linked List in Parts/README.md index 2c69b564ce9ee..860b40b88de03 100644 --- a/solution/0700-0799/0725.Split Linked List in Parts/README.md +++ b/solution/0700-0799/0725.Split Linked List in Parts/README.md @@ -60,7 +60,13 @@ tags: -### 方法一 +### 方法一:模拟 + +我们先遍历链表,得到链表的长度 $n$,然后我们计算出平均长度 $\textit{cnt} = \lfloor \frac{n}{k} \rfloor$ 和余数 $\textit{mod} = n \bmod k$。那么对于前 $\textit{mod}$ 个部分,每个部分的长度为 $\textit{cnt} + 1$,其余部分的长度为 $\textit{cnt}$。 + +接下来,我们只需要遍历链表,将链表分割成 $k$ 个部分即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(k)$。其中 $n$ 为链表的长度。 @@ -69,29 +75,32 @@ tags: ```python # Definition for singly-linked list. # class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None - - +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next class Solution: - def splitListToParts(self, root: ListNode, k: int) -> List[ListNode]: - n, cur = 0, root + def splitListToParts( + self, head: Optional[ListNode], k: int + ) -> List[Optional[ListNode]]: + n = 0 + cur = head while cur: n += 1 cur = cur.next - cur = root - width, remainder = divmod(n, k) - res = [None for _ in range(k)] + cnt, mod = divmod(n, k) + ans = [None] * k + cur = head for i in range(k): - head = cur - for j in range(width + (i < remainder) - 1): - if cur: - cur = cur.next - if cur: - cur.next, cur = None, cur.next - res[i] = head - return res + if cur is None: + break + ans[i] = cur + m = cnt + int(i < mod) + for _ in range(1, m): + cur = cur.next + nxt = cur.next + cur.next = None + cur = nxt + return ans ``` #### Java @@ -102,38 +111,147 @@ class Solution: * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { - public ListNode[] splitListToParts(ListNode root, int k) { + public ListNode[] splitListToParts(ListNode head, int k) { int n = 0; - ListNode cur = root; - while (cur != null) { + for (ListNode cur = head; cur != null; cur = cur.next) { ++n; - cur = cur.next; } - // width 表示每一部分至少含有的结点个数 - // remainder 表示前 remainder 部分,每一部分多出一个数 - int width = n / k, remainder = n % k; - ListNode[] res = new ListNode[k]; - cur = root; - for (int i = 0; i < k; ++i) { - ListNode head = cur; - for (int j = 0; j < width + ((i < remainder) ? 1 : 0) - 1; ++j) { - if (cur != null) { - cur = cur.next; - } + int cnt = n / k, mod = n % k; + ListNode[] ans = new ListNode[k]; + ListNode cur = head; + for (int i = 0; i < k && cur != null; ++i) { + ans[i] = cur; + int m = cnt + (i < mod ? 1 : 0); + for (int j = 1; j < m; ++j) { + cur = cur.next; } - if (cur != null) { - ListNode t = cur.next; - cur.next = null; - cur = t; + ListNode nxt = cur.next; + cur.next = null; + cur = nxt; + } + return ans; + } +} +``` + +#### C++ + +```cpp +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode() : val(0), next(nullptr) {} + * ListNode(int x) : val(x), next(nullptr) {} + * ListNode(int x, ListNode *next) : val(x), next(next) {} + * }; + */ +class Solution { +public: + vector splitListToParts(ListNode* head, int k) { + int n = 0; + for (ListNode* cur = head; cur != nullptr; cur = cur->next) { + ++n; + } + int cnt = n / k, mod = n % k; + vector ans(k, nullptr); + ListNode* cur = head; + for (int i = 0; i < k && cur != nullptr; ++i) { + ans[i] = cur; + int m = cnt + (i < mod ? 1 : 0); + for (int j = 1; j < m; ++j) { + cur = cur->next; } - res[i] = head; + ListNode* nxt = cur->next; + cur->next = nullptr; + cur = nxt; + } + return ans; + } +}; +``` + +#### Go + +```go +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func splitListToParts(head *ListNode, k int) []*ListNode { + n := 0 + for cur := head; cur != nil; cur = cur.Next { + n++ + } + + cnt := n / k + mod := n % k + ans := make([]*ListNode, k) + cur := head + + for i := 0; i < k && cur != nil; i++ { + ans[i] = cur + m := cnt + if i < mod { + m++ + } + for j := 1; j < m; j++ { + cur = cur.Next + } + next := cur.Next + cur.Next = nil + cur = next + } + + return ans +} +``` + +#### TypeScript + +```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 splitListToParts(head: ListNode | null, k: number): Array { + let n = 0; + for (let cur = head; cur !== null; cur = cur.next) { + n++; + } + const cnt = (n / k) | 0; + const mod = n % k; + const ans: Array = Array(k).fill(null); + let cur = head; + for (let i = 0; i < k && cur !== null; i++) { + ans[i] = cur; + let m = cnt + (i < mod ? 1 : 0); + for (let j = 1; j < m; j++) { + cur = cur.next!; } - return res; + let next = cur.next; + cur.next = null; + cur = next; } + return ans; } ``` diff --git a/solution/0700-0799/0725.Split Linked List in Parts/README_EN.md b/solution/0700-0799/0725.Split Linked List in Parts/README_EN.md index cb2023eec5412..d88f7a8178482 100644 --- a/solution/0700-0799/0725.Split Linked List in Parts/README_EN.md +++ b/solution/0700-0799/0725.Split Linked List in Parts/README_EN.md @@ -59,7 +59,13 @@ The input has been split into consecutive parts with size difference at most 1, -### Solution 1 +### Solution 1: Simulation + +First, we traverse the linked list to obtain its length $n$, and then we calculate the average length $\textit{cnt} = \lfloor \frac{n}{k} \rfloor$ and the remainder $\textit{mod} = n \bmod k$. For the first $\textit{mod}$ parts, each part has a length of $\textit{cnt} + 1$, while the lengths of the remaining parts are $\textit{cnt}$. + +Next, we just need to traverse the linked list and split it into $k$ parts. + +The time complexity is $O(n)$, and the space complexity is $O(k)$. Here, $n$ is the length of the linked list. @@ -68,29 +74,32 @@ The input has been split into consecutive parts with size difference at most 1, ```python # Definition for singly-linked list. # class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None - - +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next class Solution: - def splitListToParts(self, root: ListNode, k: int) -> List[ListNode]: - n, cur = 0, root + def splitListToParts( + self, head: Optional[ListNode], k: int + ) -> List[Optional[ListNode]]: + n = 0 + cur = head while cur: n += 1 cur = cur.next - cur = root - width, remainder = divmod(n, k) - res = [None for _ in range(k)] + cnt, mod = divmod(n, k) + ans = [None] * k + cur = head for i in range(k): - head = cur - for j in range(width + (i < remainder) - 1): - if cur: - cur = cur.next - if cur: - cur.next, cur = None, cur.next - res[i] = head - return res + if cur is None: + break + ans[i] = cur + m = cnt + int(i < mod) + for _ in range(1, m): + cur = cur.next + nxt = cur.next + cur.next = None + cur = nxt + return ans ``` #### Java @@ -101,38 +110,147 @@ class Solution: * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { - public ListNode[] splitListToParts(ListNode root, int k) { + public ListNode[] splitListToParts(ListNode head, int k) { int n = 0; - ListNode cur = root; - while (cur != null) { + for (ListNode cur = head; cur != null; cur = cur.next) { ++n; - cur = cur.next; } - // width 表示每一部分至少含有的结点个数 - // remainder 表示前 remainder 部分,每一部分多出一个数 - int width = n / k, remainder = n % k; - ListNode[] res = new ListNode[k]; - cur = root; - for (int i = 0; i < k; ++i) { - ListNode head = cur; - for (int j = 0; j < width + ((i < remainder) ? 1 : 0) - 1; ++j) { - if (cur != null) { - cur = cur.next; - } + int cnt = n / k, mod = n % k; + ListNode[] ans = new ListNode[k]; + ListNode cur = head; + for (int i = 0; i < k && cur != null; ++i) { + ans[i] = cur; + int m = cnt + (i < mod ? 1 : 0); + for (int j = 1; j < m; ++j) { + cur = cur.next; } - if (cur != null) { - ListNode t = cur.next; - cur.next = null; - cur = t; + ListNode nxt = cur.next; + cur.next = null; + cur = nxt; + } + return ans; + } +} +``` + +#### C++ + +```cpp +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode() : val(0), next(nullptr) {} + * ListNode(int x) : val(x), next(nullptr) {} + * ListNode(int x, ListNode *next) : val(x), next(next) {} + * }; + */ +class Solution { +public: + vector splitListToParts(ListNode* head, int k) { + int n = 0; + for (ListNode* cur = head; cur != nullptr; cur = cur->next) { + ++n; + } + int cnt = n / k, mod = n % k; + vector ans(k, nullptr); + ListNode* cur = head; + for (int i = 0; i < k && cur != nullptr; ++i) { + ans[i] = cur; + int m = cnt + (i < mod ? 1 : 0); + for (int j = 1; j < m; ++j) { + cur = cur->next; } - res[i] = head; + ListNode* nxt = cur->next; + cur->next = nullptr; + cur = nxt; + } + return ans; + } +}; +``` + +#### Go + +```go +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func splitListToParts(head *ListNode, k int) []*ListNode { + n := 0 + for cur := head; cur != nil; cur = cur.Next { + n++ + } + + cnt := n / k + mod := n % k + ans := make([]*ListNode, k) + cur := head + + for i := 0; i < k && cur != nil; i++ { + ans[i] = cur + m := cnt + if i < mod { + m++ + } + for j := 1; j < m; j++ { + cur = cur.Next + } + next := cur.Next + cur.Next = nil + cur = next + } + + return ans +} +``` + +#### TypeScript + +```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 splitListToParts(head: ListNode | null, k: number): Array { + let n = 0; + for (let cur = head; cur !== null; cur = cur.next) { + n++; + } + const cnt = (n / k) | 0; + const mod = n % k; + const ans: Array = Array(k).fill(null); + let cur = head; + for (let i = 0; i < k && cur !== null; i++) { + ans[i] = cur; + let m = cnt + (i < mod ? 1 : 0); + for (let j = 1; j < m; j++) { + cur = cur.next!; } - return res; + let next = cur.next; + cur.next = null; + cur = next; } + return ans; } ``` diff --git a/solution/0700-0799/0725.Split Linked List in Parts/Solution.cpp b/solution/0700-0799/0725.Split Linked List in Parts/Solution.cpp new file mode 100644 index 0000000000000..e2c895d0d9636 --- /dev/null +++ b/solution/0700-0799/0725.Split Linked List in Parts/Solution.cpp @@ -0,0 +1,33 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode() : val(0), next(nullptr) {} + * ListNode(int x) : val(x), next(nullptr) {} + * ListNode(int x, ListNode *next) : val(x), next(next) {} + * }; + */ +class Solution { +public: + vector splitListToParts(ListNode* head, int k) { + int n = 0; + for (ListNode* cur = head; cur != nullptr; cur = cur->next) { + ++n; + } + int cnt = n / k, mod = n % k; + vector ans(k, nullptr); + ListNode* cur = head; + for (int i = 0; i < k && cur != nullptr; ++i) { + ans[i] = cur; + int m = cnt + (i < mod ? 1 : 0); + for (int j = 1; j < m; ++j) { + cur = cur->next; + } + ListNode* nxt = cur->next; + cur->next = nullptr; + cur = nxt; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/0700-0799/0725.Split Linked List in Parts/Solution.go b/solution/0700-0799/0725.Split Linked List in Parts/Solution.go new file mode 100644 index 0000000000000..1ea47bd7421cb --- /dev/null +++ b/solution/0700-0799/0725.Split Linked List in Parts/Solution.go @@ -0,0 +1,34 @@ +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func splitListToParts(head *ListNode, k int) []*ListNode { + n := 0 + for cur := head; cur != nil; cur = cur.Next { + n++ + } + + cnt := n / k + mod := n % k + ans := make([]*ListNode, k) + cur := head + + for i := 0; i < k && cur != nil; i++ { + ans[i] = cur + m := cnt + if i < mod { + m++ + } + for j := 1; j < m; j++ { + cur = cur.Next + } + next := cur.Next + cur.Next = nil + cur = next + } + + return ans +} \ No newline at end of file diff --git a/solution/0700-0799/0725.Split Linked List in Parts/Solution.java b/solution/0700-0799/0725.Split Linked List in Parts/Solution.java index f59382fe22e83..fa75fd3addad7 100644 --- a/solution/0700-0799/0725.Split Linked List in Parts/Solution.java +++ b/solution/0700-0799/0725.Split Linked List in Parts/Solution.java @@ -3,36 +3,30 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { - public ListNode[] splitListToParts(ListNode root, int k) { + public ListNode[] splitListToParts(ListNode head, int k) { int n = 0; - ListNode cur = root; - while (cur != null) { + for (ListNode cur = head; cur != null; cur = cur.next) { ++n; - cur = cur.next; } - // width 表示每一部分至少含有的结点个数 - // remainder 表示前 remainder 部分,每一部分多出一个数 - int width = n / k, remainder = n % k; - ListNode[] res = new ListNode[k]; - cur = root; - for (int i = 0; i < k; ++i) { - ListNode head = cur; - for (int j = 0; j < width + ((i < remainder) ? 1 : 0) - 1; ++j) { - if (cur != null) { - cur = cur.next; - } + int cnt = n / k, mod = n % k; + ListNode[] ans = new ListNode[k]; + ListNode cur = head; + for (int i = 0; i < k && cur != null; ++i) { + ans[i] = cur; + int m = cnt + (i < mod ? 1 : 0); + for (int j = 1; j < m; ++j) { + cur = cur.next; } - if (cur != null) { - ListNode t = cur.next; - cur.next = null; - cur = t; - } - res[i] = head; + ListNode nxt = cur.next; + cur.next = null; + cur = nxt; } - return res; + return ans; } } \ No newline at end of file diff --git a/solution/0700-0799/0725.Split Linked List in Parts/Solution.py b/solution/0700-0799/0725.Split Linked List in Parts/Solution.py index 0033463d90468..2c72414dc4da1 100644 --- a/solution/0700-0799/0725.Split Linked List in Parts/Solution.py +++ b/solution/0700-0799/0725.Split Linked List in Parts/Solution.py @@ -1,25 +1,28 @@ # Definition for singly-linked list. # class ListNode: -# def __init__(self, x): -# self.val = x -# self.next = None - - +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next class Solution: - def splitListToParts(self, root: ListNode, k: int) -> List[ListNode]: - n, cur = 0, root + def splitListToParts( + self, head: Optional[ListNode], k: int + ) -> List[Optional[ListNode]]: + n = 0 + cur = head while cur: n += 1 cur = cur.next - cur = root - width, remainder = divmod(n, k) - res = [None for _ in range(k)] + cnt, mod = divmod(n, k) + ans = [None] * k + cur = head for i in range(k): - head = cur - for j in range(width + (i < remainder) - 1): - if cur: - cur = cur.next - if cur: - cur.next, cur = None, cur.next - res[i] = head - return res + if cur is None: + break + ans[i] = cur + m = cnt + int(i < mod) + for _ in range(1, m): + cur = cur.next + nxt = cur.next + cur.next = None + cur = nxt + return ans diff --git a/solution/0700-0799/0725.Split Linked List in Parts/Solution.ts b/solution/0700-0799/0725.Split Linked List in Parts/Solution.ts new file mode 100644 index 0000000000000..dda11046b241b --- /dev/null +++ b/solution/0700-0799/0725.Split Linked List in Parts/Solution.ts @@ -0,0 +1,33 @@ +/** + * 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 splitListToParts(head: ListNode | null, k: number): Array { + let n = 0; + for (let cur = head; cur !== null; cur = cur.next) { + n++; + } + const cnt = (n / k) | 0; + const mod = n % k; + const ans: Array = Array(k).fill(null); + let cur = head; + for (let i = 0; i < k && cur !== null; i++) { + ans[i] = cur; + let m = cnt + (i < mod ? 1 : 0); + for (let j = 1; j < m; j++) { + cur = cur.next!; + } + let next = cur.next; + cur.next = null; + cur = next; + } + return ans; +}