Skip to content

Commit a491049

Browse files
authored
feat: update solutions to lc problem: No.2058 (doocs#3205)
No.2058.Find the Minimum and Maximum Number of Nodes Between Critical Points
1 parent c37bbd5 commit a491049

File tree

7 files changed

+154
-221
lines changed

7 files changed

+154
-221
lines changed

solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README.md

Lines changed: 53 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ tags:
9595

9696
<!-- solution:start -->
9797

98-
### 方法一
98+
### 方法一:直接遍历
99+
100+
根据题目描述,我们需要找出链表的第一个临界点和最后一个临界点位置 $\text{first}$ 和 $\text{last}$,这样可以计算出最大距离 $\text{maxDistance} = \text{last} - \text{first}$。对于最小距离 $\text{minDistance}$,我们需要遍历链表,计算相邻两个临界点之间的距离,取最小值即可。
101+
102+
时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。
99103

100104
<!-- tabs:start -->
101105

@@ -109,23 +113,21 @@ tags:
109113
# self.next = next
110114
class Solution:
111115
def nodesBetweenCriticalPoints(self, head: Optional[ListNode]) -> List[int]:
112-
prev, curr = head, head.next
113-
first = last = None
114-
i = 1
115116
ans = [inf, -inf]
116-
while curr.next:
117-
if curr.val < min(prev.val, curr.next.val) or curr.val > max(
118-
prev.val, curr.next.val
119-
):
120-
if last is None:
117+
first = last = -1
118+
i = 0
119+
while head.next.next:
120+
a, b, c = head.val, head.next.val, head.next.next.val
121+
if a > b < c or a < b > c:
122+
if last == -1:
121123
first = last = i
122124
else:
123125
ans[0] = min(ans[0], i - last)
124-
ans[1] = i - first
125126
last = i
127+
ans[1] = max(ans[1], last - first)
126128
i += 1
127-
prev, curr = curr, curr.next
128-
return ans if first != last else [-1, -1]
129+
head = head.next
130+
return [-1, -1] if first == last else ans
129131
```
130132

131133
#### Java
@@ -142,28 +144,21 @@ class Solution:
142144
* }
143145
*/
144146
class Solution {
145-
146147
public int[] nodesBetweenCriticalPoints(ListNode head) {
147-
ListNode prev = head;
148-
ListNode curr = head.next;
149-
int first = 0, last = 0;
150-
int i = 1;
151-
int[] ans = new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE};
152-
while (curr.next != null) {
153-
if (curr.val < Math.min(prev.val, curr.next.val)
154-
|| curr.val > Math.max(prev.val, curr.next.val)) {
155-
if (last == 0) {
148+
int[] ans = {1 << 30, 0};
149+
int first = -1, last = -1;
150+
for (int i = 0; head.next.next != null; head = head.next, ++i) {
151+
int a = head.val, b = head.next.val, c = head.next.next.val;
152+
if (b < Math.min(a, c) || b > Math.max(a, c)) {
153+
if (last == -1) {
156154
first = i;
157155
last = i;
158156
} else {
159157
ans[0] = Math.min(ans[0], i - last);
160-
ans[1] = i - first;
161158
last = i;
159+
ans[1] = Math.max(ans[1], last - first);
162160
}
163161
}
164-
++i;
165-
prev = curr;
166-
curr = curr.next;
167162
}
168163
return first == last ? new int[] {-1, -1} : ans;
169164
}
@@ -186,27 +181,22 @@ class Solution {
186181
class Solution {
187182
public:
188183
vector<int> nodesBetweenCriticalPoints(ListNode* head) {
189-
ListNode* prev = head;
190-
ListNode* curr = head->next;
191-
int first = 0, last = 0;
192-
int i = 1;
193-
vector<int> ans(2, INT_MAX);
194-
while (curr->next) {
195-
if (curr->val < min(prev->val, curr->next->val) || curr->val > max(prev->val, curr->next->val)) {
196-
if (last == 0)
184+
vector<int> ans = {1 << 30, 0};
185+
int first = -1, last = -1;
186+
for (int i = 0; head->next->next; head = head->next, ++i) {
187+
int a = head->val, b = head->next->val, c = head->next->next->val;
188+
if (b < min(a, c) || b > max(a, c)) {
189+
if (last == -1) {
197190
first = i;
198-
else {
191+
last = i;
192+
} else {
199193
ans[0] = min(ans[0], i - last);
200-
ans[1] = i - first;
194+
last = i;
195+
ans[1] = max(ans[1], last - first);
201196
}
202-
last = i;
203197
}
204-
++i;
205-
prev = curr;
206-
curr = curr->next;
207198
}
208-
if (first == last) return {-1, -1};
209-
return ans;
199+
return first == last ? vector<int>{-1, -1} : ans;
210200
}
211201
};
212202
```
@@ -222,22 +212,19 @@ public:
222212
* }
223213
*/
224214
func nodesBetweenCriticalPoints(head *ListNode) []int {
225-
prev, curr := head, head.Next
226-
first, last := 0, 0
227-
i := 1
228-
ans := []int{math.MaxInt32, 0}
229-
for curr.Next != nil {
230-
if curr.Val < min(prev.Val, curr.Next.Val) || curr.Val > max(prev.Val, curr.Next.Val) {
231-
if last == 0 {
215+
ans := []int{1 << 30, 0}
216+
first, last := -1, -1
217+
for i := 0; head.Next.Next != nil; head, i = head.Next, i+1 {
218+
a, b, c := head.Val, head.Next.Val, head.Next.Next.Val
219+
if b < min(a, c) || b > max(a, c) {
220+
if last == -1 {
232221
first, last = i, i
233222
} else {
234223
ans[0] = min(ans[0], i-last)
235-
ans[1] = i - first
236224
last = i
225+
ans[1] = max(ans[1], last-first)
237226
}
238227
}
239-
i++
240-
prev, curr = curr, curr.Next
241228
}
242229
if first == last {
243230
return []int{-1, -1}
@@ -262,30 +249,22 @@ func nodesBetweenCriticalPoints(head *ListNode) []int {
262249
*/
263250

264251
function nodesBetweenCriticalPoints(head: ListNode | null): number[] {
265-
let idx = 1;
266-
let pre = head.val;
267-
head = head.next;
268-
let nums = [];
269-
while (head.next != null) {
270-
let val = head.val,
271-
post = head.next.val;
272-
if (pre < val && val > post) {
273-
nums.push(idx);
274-
}
275-
if (pre > val && val < post) {
276-
nums.push(idx);
252+
const ans: number[] = [Infinity, 0];
253+
let [first, last] = [-1, -1];
254+
for (let i = 0; head.next.next; head = head.next, ++i) {
255+
const [a, b, c] = [head.val, head.next.val, head.next.next.val];
256+
if (b < Math.min(a, c) || b > Math.max(a, c)) {
257+
if (last < 0) {
258+
first = i;
259+
last = i;
260+
} else {
261+
ans[0] = Math.min(ans[0], i - last);
262+
last = i;
263+
ans[1] = Math.max(ans[1], last - first);
264+
}
277265
}
278-
pre = val;
279-
idx++;
280-
head = head.next;
281-
}
282-
let n = nums.length;
283-
if (n < 2) return [-1, -1];
284-
let min = Infinity;
285-
for (let i = 1; i < n; i++) {
286-
min = Math.min(nums[i] - nums[i - 1], min);
287266
}
288-
return [min, nums[n - 1] - nums[0]];
267+
return first === last ? [-1, -1] : ans;
289268
}
290269
```
291270

solution/2000-2099/2058.Find the Minimum and Maximum Number of Nodes Between Critical Points/README_EN.md

Lines changed: 53 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,11 @@ Note that the last node is not considered a local maxima because it does not hav
7777

7878
<!-- solution:start -->
7979

80-
### Solution 1
80+
### Solution 1: Direct Traversal
81+
82+
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.
83+
84+
The time complexity is $O(n)$, where $n$ is the length of the linked list. The space complexity is $O(1)$.
8185

8286
<!-- tabs:start -->
8387

@@ -91,23 +95,21 @@ Note that the last node is not considered a local maxima because it does not hav
9195
# self.next = next
9296
class Solution:
9397
def nodesBetweenCriticalPoints(self, head: Optional[ListNode]) -> List[int]:
94-
prev, curr = head, head.next
95-
first = last = None
96-
i = 1
9798
ans = [inf, -inf]
98-
while curr.next:
99-
if curr.val < min(prev.val, curr.next.val) or curr.val > max(
100-
prev.val, curr.next.val
101-
):
102-
if last is None:
99+
first = last = -1
100+
i = 0
101+
while head.next.next:
102+
a, b, c = head.val, head.next.val, head.next.next.val
103+
if a > b < c or a < b > c:
104+
if last == -1:
103105
first = last = i
104106
else:
105107
ans[0] = min(ans[0], i - last)
106-
ans[1] = i - first
107108
last = i
109+
ans[1] = max(ans[1], last - first)
108110
i += 1
109-
prev, curr = curr, curr.next
110-
return ans if first != last else [-1, -1]
111+
head = head.next
112+
return [-1, -1] if first == last else ans
111113
```
112114

113115
#### Java
@@ -124,28 +126,21 @@ class Solution:
124126
* }
125127
*/
126128
class Solution {
127-
128129
public int[] nodesBetweenCriticalPoints(ListNode head) {
129-
ListNode prev = head;
130-
ListNode curr = head.next;
131-
int first = 0, last = 0;
132-
int i = 1;
133-
int[] ans = new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE};
134-
while (curr.next != null) {
135-
if (curr.val < Math.min(prev.val, curr.next.val)
136-
|| curr.val > Math.max(prev.val, curr.next.val)) {
137-
if (last == 0) {
130+
int[] ans = {1 << 30, 0};
131+
int first = -1, last = -1;
132+
for (int i = 0; head.next.next != null; head = head.next, ++i) {
133+
int a = head.val, b = head.next.val, c = head.next.next.val;
134+
if (b < Math.min(a, c) || b > Math.max(a, c)) {
135+
if (last == -1) {
138136
first = i;
139137
last = i;
140138
} else {
141139
ans[0] = Math.min(ans[0], i - last);
142-
ans[1] = i - first;
143140
last = i;
141+
ans[1] = Math.max(ans[1], last - first);
144142
}
145143
}
146-
++i;
147-
prev = curr;
148-
curr = curr.next;
149144
}
150145
return first == last ? new int[] {-1, -1} : ans;
151146
}
@@ -168,27 +163,22 @@ class Solution {
168163
class Solution {
169164
public:
170165
vector<int> nodesBetweenCriticalPoints(ListNode* head) {
171-
ListNode* prev = head;
172-
ListNode* curr = head->next;
173-
int first = 0, last = 0;
174-
int i = 1;
175-
vector<int> ans(2, INT_MAX);
176-
while (curr->next) {
177-
if (curr->val < min(prev->val, curr->next->val) || curr->val > max(prev->val, curr->next->val)) {
178-
if (last == 0)
166+
vector<int> ans = {1 << 30, 0};
167+
int first = -1, last = -1;
168+
for (int i = 0; head->next->next; head = head->next, ++i) {
169+
int a = head->val, b = head->next->val, c = head->next->next->val;
170+
if (b < min(a, c) || b > max(a, c)) {
171+
if (last == -1) {
179172
first = i;
180-
else {
173+
last = i;
174+
} else {
181175
ans[0] = min(ans[0], i - last);
182-
ans[1] = i - first;
176+
last = i;
177+
ans[1] = max(ans[1], last - first);
183178
}
184-
last = i;
185179
}
186-
++i;
187-
prev = curr;
188-
curr = curr->next;
189180
}
190-
if (first == last) return {-1, -1};
191-
return ans;
181+
return first == last ? vector<int>{-1, -1} : ans;
192182
}
193183
};
194184
```
@@ -204,22 +194,19 @@ public:
204194
* }
205195
*/
206196
func nodesBetweenCriticalPoints(head *ListNode) []int {
207-
prev, curr := head, head.Next
208-
first, last := 0, 0
209-
i := 1
210-
ans := []int{math.MaxInt32, 0}
211-
for curr.Next != nil {
212-
if curr.Val < min(prev.Val, curr.Next.Val) || curr.Val > max(prev.Val, curr.Next.Val) {
213-
if last == 0 {
197+
ans := []int{1 << 30, 0}
198+
first, last := -1, -1
199+
for i := 0; head.Next.Next != nil; head, i = head.Next, i+1 {
200+
a, b, c := head.Val, head.Next.Val, head.Next.Next.Val
201+
if b < min(a, c) || b > max(a, c) {
202+
if last == -1 {
214203
first, last = i, i
215204
} else {
216205
ans[0] = min(ans[0], i-last)
217-
ans[1] = i - first
218206
last = i
207+
ans[1] = max(ans[1], last-first)
219208
}
220209
}
221-
i++
222-
prev, curr = curr, curr.Next
223210
}
224211
if first == last {
225212
return []int{-1, -1}
@@ -244,30 +231,22 @@ func nodesBetweenCriticalPoints(head *ListNode) []int {
244231
*/
245232

246233
function nodesBetweenCriticalPoints(head: ListNode | null): number[] {
247-
let idx = 1;
248-
let pre = head.val;
249-
head = head.next;
250-
let nums = [];
251-
while (head.next != null) {
252-
let val = head.val,
253-
post = head.next.val;
254-
if (pre < val && val > post) {
255-
nums.push(idx);
256-
}
257-
if (pre > val && val < post) {
258-
nums.push(idx);
234+
const ans: number[] = [Infinity, 0];
235+
let [first, last] = [-1, -1];
236+
for (let i = 0; head.next.next; head = head.next, ++i) {
237+
const [a, b, c] = [head.val, head.next.val, head.next.next.val];
238+
if (b < Math.min(a, c) || b > Math.max(a, c)) {
239+
if (last < 0) {
240+
first = i;
241+
last = i;
242+
} else {
243+
ans[0] = Math.min(ans[0], i - last);
244+
last = i;
245+
ans[1] = Math.max(ans[1], last - first);
246+
}
259247
}
260-
pre = val;
261-
idx++;
262-
head = head.next;
263-
}
264-
let n = nums.length;
265-
if (n < 2) return [-1, -1];
266-
let min = Infinity;
267-
for (let i = 1; i < n; i++) {
268-
min = Math.min(nums[i] - nums[i - 1], min);
269248
}
270-
return [min, nums[n - 1] - nums[0]];
249+
return first === last ? [-1, -1] : ans;
271250
}
272251
```
273252

0 commit comments

Comments
 (0)