跳转至

2058. 找出临界点之间的最小和最大距离

题目描述

链表中的 临界点 定义为一个 局部极大值点 局部极小值点 。

如果当前节点的值 严格大于 前一个节点和后一个节点,那么这个节点就是一个  局部极大值点

如果当前节点的值 严格小于 前一个节点和后一个节点,那么这个节点就是一个  局部极小值点

注意:节点只有在同时存在前一个节点和后一个节点的情况下,才能成为一个 局部极大值点 / 极小值点

给你一个链表 head ,返回一个长度为 2 的数组 [minDistance, maxDistance] ,其中 minDistance 是任意两个不同临界点之间的最小距离,maxDistance 是任意两个不同临界点之间的最大距离。如果临界点少于两个,则返回 [-1,-1]

 

示例 1:

输入:head = [3,1]
输出:[-1,-1]
解释:链表 [3,1] 中不存在临界点。

示例 2:

输入:head = [5,3,1,2,5,1,2]
输出:[1,3]
解释:存在三个临界点:
- [5,3,1,2,5,1,2]:第三个节点是一个局部极小值点,因为 1 比 3 和 2 小。
- [5,3,1,2,5,1,2]:第五个节点是一个局部极大值点,因为 5 比 2 和 1 大。
- [5,3,1,2,5,1,2]:第六个节点是一个局部极小值点,因为 1 比 5 和 2 小。
第五个节点和第六个节点之间距离最小。minDistance = 6 - 5 = 1 。
第三个节点和第六个节点之间距离最大。maxDistance = 6 - 3 = 3 。

示例 3:

输入:head = [1,3,2,2,3,2,2,2,7]
输出:[3,3]
解释:存在两个临界点:
- [1,3,2,2,3,2,2,2,7]:第二个节点是一个局部极大值点,因为 3 比 1 和 2 大。
- [1,3,2,2,3,2,2,2,7]:第五个节点是一个局部极大值点,因为 3 比 2 和 2 大。
最小和最大距离都存在于第二个节点和第五个节点之间。
因此,minDistance 和 maxDistance 是 5 - 2 = 3 。
注意,最后一个节点不算一个局部极大值点,因为它之后就没有节点了。

示例 4:

输入:head = [2,3,3,2]
输出:[-1,-1]
解释:链表 [2,3,3,2] 中不存在临界点。

 

提示:

  • 链表中节点的数量在范围 [2, 105]
  • 1 <= Node.val <= 105

解法

方法一:直接遍历

根据题目描述,我们需要找出链表的第一个临界点和最后一个临界点位置 $\textit{first}$ 和 $\textit{last}$,这样可以计算出最大距离 $\textit{maxDistance} = \textit{last} - \textit{first}$。对于最小距离 $\textit{minDistance}$,我们需要遍历链表,计算相邻两个临界点之间的距离,取最小值即可。

时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def nodesBetweenCriticalPoints(self, head: Optional[ListNode]) -> List[int]:
        ans = [inf, -inf]
        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)
                    last = i
                    ans[1] = max(ans[1], last - first)
            i += 1
            head = head.next
        return [-1, -1] if first == last else ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public int[] nodesBetweenCriticalPoints(ListNode head) {
        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);
                    last = i;
                    ans[1] = Math.max(ans[1], last - first);
                }
            }
        }
        return first == last ? new int[] {-1, -1} : ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * 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<int> nodesBetweenCriticalPoints(ListNode* head) {
        vector<int> 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;
                    last = i;
                } else {
                    ans[0] = min(ans[0], i - last);
                    last = i;
                    ans[1] = max(ans[1], last - first);
                }
            }
        }
        return first == last ? vector<int>{-1, -1} : ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func nodesBetweenCriticalPoints(head *ListNode) []int {
    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)
                last = i
                ans[1] = max(ans[1], last-first)
            }
        }
    }
    if first == last {
        return []int{-1, -1}
    }
    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
 * 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 nodesBetweenCriticalPoints(head: ListNode | null): number[] {
    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);
            }
        }
    }
    return first === last ? [-1, -1] : ans;
}

评论