From 406cbf857fbe55d8b4893b8c741407660d678e18 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 5 Jul 2024 20:11:52 +0800 Subject: [PATCH] feat: update solutions to lc problem: No.2058 No.2058.Find the Minimum and Maximum Number of Nodes Between Critical Points --- .../README.md | 127 ++++++++---------- .../README_EN.md | 127 ++++++++---------- .../Solution.cpp | 27 ++-- .../Solution.go | 17 +-- .../Solution.java | 21 +-- .../Solution.py | 20 ++- .../Solution.ts | 36 ++--- 7 files changed, 154 insertions(+), 221 deletions(-) diff --git a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README.md b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README.md index 88e778e46bb73..c771acaebd79c 100644 --- a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README.md +++ b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README.md @@ -95,7 +95,11 @@ tags: -### 方法一 +### 方法一:直接遍历 + +根据题目描述,我们需要找出链表的第一个临界点和最后一个临界点位置 $\text{first}$ 和 $\text{last}$,这样可以计算出最大距离 $\text{maxDistance} = \text{last} - \text{first}$。对于最小距离 $\text{minDistance}$,我们需要遍历链表,计算相邻两个临界点之间的距离,取最小值即可。 + +时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。 @@ -109,23 +113,21 @@ tags: # self.next = next class Solution: def nodesBetweenCriticalPoints(self, head: Optional[ListNode]) -> List[int]: - prev, curr = head, head.next - first = last = None - i = 1 ans = [inf, -inf] - while curr.next: - if curr.val < min(prev.val, curr.next.val) or curr.val > max( - prev.val, curr.next.val - ): - if last is None: + first = last = -1 + i = 0 + while head.next.next: + a, b, c = head.val, head.next.val, head.next.next.val + if a > b < c or a < b > c: + if last == -1: first = last = i else: ans[0] = min(ans[0], i - last) - ans[1] = i - first last = i + ans[1] = max(ans[1], last - first) i += 1 - prev, curr = curr, curr.next - return ans if first != last else [-1, -1] + head = head.next + return [-1, -1] if first == last else ans ``` #### Java @@ -142,28 +144,21 @@ class Solution: * } */ class Solution { - public int[] nodesBetweenCriticalPoints(ListNode head) { - ListNode prev = head; - ListNode curr = head.next; - int first = 0, last = 0; - int i = 1; - int[] ans = new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE}; - while (curr.next != null) { - if (curr.val < Math.min(prev.val, curr.next.val) - || curr.val > Math.max(prev.val, curr.next.val)) { - if (last == 0) { + int[] ans = {1 << 30, 0}; + int first = -1, last = -1; + for (int i = 0; head.next.next != null; head = head.next, ++i) { + int a = head.val, b = head.next.val, c = head.next.next.val; + if (b < Math.min(a, c) || b > Math.max(a, c)) { + if (last == -1) { first = i; last = i; } else { ans[0] = Math.min(ans[0], i - last); - ans[1] = i - first; last = i; + ans[1] = Math.max(ans[1], last - first); } } - ++i; - prev = curr; - curr = curr.next; } return first == last ? new int[] {-1, -1} : ans; } @@ -186,27 +181,22 @@ class Solution { class Solution { public: vector nodesBetweenCriticalPoints(ListNode* head) { - ListNode* prev = head; - ListNode* curr = head->next; - int first = 0, last = 0; - int i = 1; - vector ans(2, INT_MAX); - while (curr->next) { - if (curr->val < min(prev->val, curr->next->val) || curr->val > max(prev->val, curr->next->val)) { - if (last == 0) + vector ans = {1 << 30, 0}; + int first = -1, last = -1; + for (int i = 0; head->next->next; head = head->next, ++i) { + int a = head->val, b = head->next->val, c = head->next->next->val; + if (b < min(a, c) || b > max(a, c)) { + if (last == -1) { first = i; - else { + last = i; + } else { ans[0] = min(ans[0], i - last); - ans[1] = i - first; + last = i; + ans[1] = max(ans[1], last - first); } - last = i; } - ++i; - prev = curr; - curr = curr->next; } - if (first == last) return {-1, -1}; - return ans; + return first == last ? vector{-1, -1} : ans; } }; ``` @@ -222,22 +212,19 @@ public: * } */ func nodesBetweenCriticalPoints(head *ListNode) []int { - prev, curr := head, head.Next - first, last := 0, 0 - i := 1 - ans := []int{math.MaxInt32, 0} - for curr.Next != nil { - if curr.Val < min(prev.Val, curr.Next.Val) || curr.Val > max(prev.Val, curr.Next.Val) { - if last == 0 { + ans := []int{1 << 30, 0} + first, last := -1, -1 + for i := 0; head.Next.Next != nil; head, i = head.Next, i+1 { + a, b, c := head.Val, head.Next.Val, head.Next.Next.Val + if b < min(a, c) || b > max(a, c) { + if last == -1 { first, last = i, i } else { ans[0] = min(ans[0], i-last) - ans[1] = i - first last = i + ans[1] = max(ans[1], last-first) } } - i++ - prev, curr = curr, curr.Next } if first == last { return []int{-1, -1} @@ -262,30 +249,22 @@ func nodesBetweenCriticalPoints(head *ListNode) []int { */ function nodesBetweenCriticalPoints(head: ListNode | null): number[] { - let idx = 1; - let pre = head.val; - head = head.next; - let nums = []; - while (head.next != null) { - let val = head.val, - post = head.next.val; - if (pre < val && val > post) { - nums.push(idx); - } - if (pre > val && val < post) { - nums.push(idx); + const ans: number[] = [Infinity, 0]; + let [first, last] = [-1, -1]; + for (let i = 0; head.next.next; head = head.next, ++i) { + const [a, b, c] = [head.val, head.next.val, head.next.next.val]; + if (b < Math.min(a, c) || b > Math.max(a, c)) { + if (last < 0) { + first = i; + last = i; + } else { + ans[0] = Math.min(ans[0], i - last); + last = i; + ans[1] = Math.max(ans[1], last - first); + } } - pre = val; - idx++; - head = head.next; - } - let n = nums.length; - if (n < 2) return [-1, -1]; - let min = Infinity; - for (let i = 1; i < n; i++) { - min = Math.min(nums[i] - nums[i - 1], min); } - return [min, nums[n - 1] - nums[0]]; + return first === last ? [-1, -1] : ans; } ``` diff --git a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README_EN.md b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README_EN.md index c5dab213e4d63..1675eed3844cb 100644 --- a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README_EN.md +++ b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README_EN.md @@ -77,7 +77,11 @@ Note that the last node is not considered a local maxima because it does not hav -### Solution 1 +### Solution 1: Direct Traversal + +Based on the problem description, we need to find the positions of the first and last critical points in the linked list, $\text{first}$ and $\text{last}$, respectively. This allows us to calculate the maximum distance $\text{maxDistance} = \text{last} - \text{first}$. For the minimum distance $\text{minDistance}$, we need to traverse the linked list, calculate the distance between two adjacent critical points, and take the minimum value. + +The time complexity is $O(n)$, where $n$ is the length of the linked list. The space complexity is $O(1)$. @@ -91,23 +95,21 @@ Note that the last node is not considered a local maxima because it does not hav # self.next = next class Solution: def nodesBetweenCriticalPoints(self, head: Optional[ListNode]) -> List[int]: - prev, curr = head, head.next - first = last = None - i = 1 ans = [inf, -inf] - while curr.next: - if curr.val < min(prev.val, curr.next.val) or curr.val > max( - prev.val, curr.next.val - ): - if last is None: + first = last = -1 + i = 0 + while head.next.next: + a, b, c = head.val, head.next.val, head.next.next.val + if a > b < c or a < b > c: + if last == -1: first = last = i else: ans[0] = min(ans[0], i - last) - ans[1] = i - first last = i + ans[1] = max(ans[1], last - first) i += 1 - prev, curr = curr, curr.next - return ans if first != last else [-1, -1] + head = head.next + return [-1, -1] if first == last else ans ``` #### Java @@ -124,28 +126,21 @@ class Solution: * } */ class Solution { - public int[] nodesBetweenCriticalPoints(ListNode head) { - ListNode prev = head; - ListNode curr = head.next; - int first = 0, last = 0; - int i = 1; - int[] ans = new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE}; - while (curr.next != null) { - if (curr.val < Math.min(prev.val, curr.next.val) - || curr.val > Math.max(prev.val, curr.next.val)) { - if (last == 0) { + int[] ans = {1 << 30, 0}; + int first = -1, last = -1; + for (int i = 0; head.next.next != null; head = head.next, ++i) { + int a = head.val, b = head.next.val, c = head.next.next.val; + if (b < Math.min(a, c) || b > Math.max(a, c)) { + if (last == -1) { first = i; last = i; } else { ans[0] = Math.min(ans[0], i - last); - ans[1] = i - first; last = i; + ans[1] = Math.max(ans[1], last - first); } } - ++i; - prev = curr; - curr = curr.next; } return first == last ? new int[] {-1, -1} : ans; } @@ -168,27 +163,22 @@ class Solution { class Solution { public: vector nodesBetweenCriticalPoints(ListNode* head) { - ListNode* prev = head; - ListNode* curr = head->next; - int first = 0, last = 0; - int i = 1; - vector ans(2, INT_MAX); - while (curr->next) { - if (curr->val < min(prev->val, curr->next->val) || curr->val > max(prev->val, curr->next->val)) { - if (last == 0) + vector ans = {1 << 30, 0}; + int first = -1, last = -1; + for (int i = 0; head->next->next; head = head->next, ++i) { + int a = head->val, b = head->next->val, c = head->next->next->val; + if (b < min(a, c) || b > max(a, c)) { + if (last == -1) { first = i; - else { + last = i; + } else { ans[0] = min(ans[0], i - last); - ans[1] = i - first; + last = i; + ans[1] = max(ans[1], last - first); } - last = i; } - ++i; - prev = curr; - curr = curr->next; } - if (first == last) return {-1, -1}; - return ans; + return first == last ? vector{-1, -1} : ans; } }; ``` @@ -204,22 +194,19 @@ public: * } */ func nodesBetweenCriticalPoints(head *ListNode) []int { - prev, curr := head, head.Next - first, last := 0, 0 - i := 1 - ans := []int{math.MaxInt32, 0} - for curr.Next != nil { - if curr.Val < min(prev.Val, curr.Next.Val) || curr.Val > max(prev.Val, curr.Next.Val) { - if last == 0 { + ans := []int{1 << 30, 0} + first, last := -1, -1 + for i := 0; head.Next.Next != nil; head, i = head.Next, i+1 { + a, b, c := head.Val, head.Next.Val, head.Next.Next.Val + if b < min(a, c) || b > max(a, c) { + if last == -1 { first, last = i, i } else { ans[0] = min(ans[0], i-last) - ans[1] = i - first last = i + ans[1] = max(ans[1], last-first) } } - i++ - prev, curr = curr, curr.Next } if first == last { return []int{-1, -1} @@ -244,30 +231,22 @@ func nodesBetweenCriticalPoints(head *ListNode) []int { */ function nodesBetweenCriticalPoints(head: ListNode | null): number[] { - let idx = 1; - let pre = head.val; - head = head.next; - let nums = []; - while (head.next != null) { - let val = head.val, - post = head.next.val; - if (pre < val && val > post) { - nums.push(idx); - } - if (pre > val && val < post) { - nums.push(idx); + const ans: number[] = [Infinity, 0]; + let [first, last] = [-1, -1]; + for (let i = 0; head.next.next; head = head.next, ++i) { + const [a, b, c] = [head.val, head.next.val, head.next.next.val]; + if (b < Math.min(a, c) || b > Math.max(a, c)) { + if (last < 0) { + first = i; + last = i; + } else { + ans[0] = Math.min(ans[0], i - last); + last = i; + ans[1] = Math.max(ans[1], last - first); + } } - pre = val; - idx++; - head = head.next; - } - let n = nums.length; - if (n < 2) return [-1, -1]; - let min = Infinity; - for (let i = 1; i < n; i++) { - min = Math.min(nums[i] - nums[i - 1], min); } - return [min, nums[n - 1] - nums[0]]; + return first === last ? [-1, -1] : ans; } ``` diff --git a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.cpp b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.cpp index 382138ff846be..2620f9c0cc983 100644 --- a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.cpp +++ b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.cpp @@ -11,26 +11,21 @@ class Solution { public: vector nodesBetweenCriticalPoints(ListNode* head) { - ListNode* prev = head; - ListNode* curr = head->next; - int first = 0, last = 0; - int i = 1; - vector ans(2, INT_MAX); - while (curr->next) { - if (curr->val < min(prev->val, curr->next->val) || curr->val > max(prev->val, curr->next->val)) { - if (last == 0) + vector ans = {1 << 30, 0}; + int first = -1, last = -1; + for (int i = 0; head->next->next; head = head->next, ++i) { + int a = head->val, b = head->next->val, c = head->next->next->val; + if (b < min(a, c) || b > max(a, c)) { + if (last == -1) { first = i; - else { + last = i; + } else { ans[0] = min(ans[0], i - last); - ans[1] = i - first; + last = i; + ans[1] = max(ans[1], last - first); } - last = i; } - ++i; - prev = curr; - curr = curr->next; } - if (first == last) return {-1, -1}; - return ans; + return first == last ? vector{-1, -1} : ans; } }; \ No newline at end of file diff --git a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.go b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.go index b97045707c7a5..05668eff7cd34 100644 --- a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.go +++ b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.go @@ -6,22 +6,19 @@ * } */ func nodesBetweenCriticalPoints(head *ListNode) []int { - prev, curr := head, head.Next - first, last := 0, 0 - i := 1 - ans := []int{math.MaxInt32, 0} - for curr.Next != nil { - if curr.Val < min(prev.Val, curr.Next.Val) || curr.Val > max(prev.Val, curr.Next.Val) { - if last == 0 { + ans := []int{1 << 30, 0} + first, last := -1, -1 + for i := 0; head.Next.Next != nil; head, i = head.Next, i+1 { + a, b, c := head.Val, head.Next.Val, head.Next.Next.Val + if b < min(a, c) || b > max(a, c) { + if last == -1 { first, last = i, i } else { ans[0] = min(ans[0], i-last) - ans[1] = i - first last = i + ans[1] = max(ans[1], last-first) } } - i++ - prev, curr = curr, curr.Next } if first == last { return []int{-1, -1} diff --git a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.java b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.java index 35561da25d1f7..66e544b4d45a4 100644 --- a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.java +++ b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.java @@ -9,28 +9,21 @@ * } */ class Solution { - public int[] nodesBetweenCriticalPoints(ListNode head) { - ListNode prev = head; - ListNode curr = head.next; - int first = 0, last = 0; - int i = 1; - int[] ans = new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE}; - while (curr.next != null) { - if (curr.val < Math.min(prev.val, curr.next.val) - || curr.val > Math.max(prev.val, curr.next.val)) { - if (last == 0) { + int[] ans = {1 << 30, 0}; + int first = -1, last = -1; + for (int i = 0; head.next.next != null; head = head.next, ++i) { + int a = head.val, b = head.next.val, c = head.next.next.val; + if (b < Math.min(a, c) || b > Math.max(a, c)) { + if (last == -1) { first = i; last = i; } else { ans[0] = Math.min(ans[0], i - last); - ans[1] = i - first; last = i; + ans[1] = Math.max(ans[1], last - first); } } - ++i; - prev = curr; - curr = curr.next; } return first == last ? new int[] {-1, -1} : ans; } diff --git a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.py b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.py index 7b2d3d4761446..cd771b4a91030 100644 --- a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.py +++ b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.py @@ -5,20 +5,18 @@ # self.next = next class Solution: def nodesBetweenCriticalPoints(self, head: Optional[ListNode]) -> List[int]: - prev, curr = head, head.next - first = last = None - i = 1 ans = [inf, -inf] - while curr.next: - if curr.val < min(prev.val, curr.next.val) or curr.val > max( - prev.val, curr.next.val - ): - if last is None: + first = last = -1 + i = 0 + while head.next.next: + a, b, c = head.val, head.next.val, head.next.next.val + if a > b < c or a < b > c: + if last == -1: first = last = i else: ans[0] = min(ans[0], i - last) - ans[1] = i - first last = i + ans[1] = max(ans[1], last - first) i += 1 - prev, curr = curr, curr.next - return ans if first != last else [-1, -1] + head = head.next + return [-1, -1] if first == last else ans diff --git a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.ts b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.ts index 8978a8b83ee05..dc8021f532c5e 100644 --- a/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.ts +++ b/solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/Solution.ts @@ -11,28 +11,20 @@ */ function nodesBetweenCriticalPoints(head: ListNode | null): number[] { - let idx = 1; - let pre = head.val; - head = head.next; - let nums = []; - while (head.next != null) { - let val = head.val, - post = head.next.val; - if (pre < val && val > post) { - nums.push(idx); + const ans: number[] = [Infinity, 0]; + let [first, last] = [-1, -1]; + for (let i = 0; head.next.next; head = head.next, ++i) { + const [a, b, c] = [head.val, head.next.val, head.next.next.val]; + if (b < Math.min(a, c) || b > Math.max(a, c)) { + if (last < 0) { + first = i; + last = i; + } else { + ans[0] = Math.min(ans[0], i - last); + last = i; + ans[1] = Math.max(ans[1], last - first); + } } - if (pre > val && val < post) { - nums.push(idx); - } - pre = val; - idx++; - head = head.next; - } - let n = nums.length; - if (n < 2) return [-1, -1]; - let min = Infinity; - for (let i = 1; i < n; i++) { - min = Math.min(nums[i] - nums[i - 1], min); } - return [min, nums[n - 1] - nums[0]]; + return first === last ? [-1, -1] : ans; }