Find the Minimum and Maximum Number of Nodes Between Critical Points

medium linked list

Problem

A critical point is a node (not head or tail) whose value is strictly greater than both neighbors (local max) or strictly less than both (local min). Return [minDistance, maxDistance] between any two critical points; return [-1, -1] if fewer than two exist.

Inputhead = [5, 3, 1, 2, 5, 1, 2]
Output[1, 3]
Critical points are at indices 2 (1, local min), 4 (5, local max), 5 (1, local min). Min gap = 5−4 = 1; max gap = 5−2 = 3.

def nodes_between_critical_points(head):
    first = last = -1
    min_dist = float("inf")
    prev_idx = -1
    prev = head
    cur = head.next
    i = 1
    while cur and cur.next:
        if (cur.val > prev.val and cur.val > cur.next.val) or \
           (cur.val < prev.val and cur.val < cur.next.val):
            if first == -1:
                first = i
            else:
                min_dist = min(min_dist, i - prev_idx)
            last = i
            prev_idx = i
        prev = cur
        cur = cur.next
        i += 1
    if first == last:
        return [-1, -1]
    return [min_dist, last - first]
function nodesBetweenCriticalPoints(head) {
  let first = -1, last = -1, minDist = Infinity, prevIdx = -1;
  let prev = head, cur = head.next, i = 1;
  while (cur && cur.next) {
    const isMax = cur.val > prev.val && cur.val > cur.next.val;
    const isMin = cur.val < prev.val && cur.val < cur.next.val;
    if (isMax || isMin) {
      if (first === -1) first = i;
      else minDist = Math.min(minDist, i - prevIdx);
      last = i;
      prevIdx = i;
    }
    prev = cur;
    cur = cur.next;
    i++;
  }
  if (first === last) return [-1, -1];
  return [minDist, last - first];
}
class Solution {
    public int[] nodesBetweenCriticalPoints(ListNode head) {
        int first = -1, last = -1, minDist = Integer.MAX_VALUE, prevIdx = -1;
        ListNode prev = head, cur = head.next;
        int i = 1;
        while (cur != null && cur.next != null) {
            boolean isMax = cur.val > prev.val && cur.val > cur.next.val;
            boolean isMin = cur.val < prev.val && cur.val < cur.next.val;
            if (isMax || isMin) {
                if (first == -1) first = i;
                else minDist = Math.min(minDist, i - prevIdx);
                last = i;
                prevIdx = i;
            }
            prev = cur;
            cur = cur.next;
            i++;
        }
        if (first == last) return new int[]{-1, -1};
        return new int[]{minDist, last - first};
    }
}
vector<int> nodesBetweenCriticalPoints(ListNode* head) {
    int first = -1, last = -1, minDist = INT_MAX, prevIdx = -1;
    ListNode* prev = head;
    ListNode* cur = head->next;
    int i = 1;
    while (cur && cur->next) {
        bool isMax = cur->val > prev->val && cur->val > cur->next->val;
        bool isMin = cur->val < prev->val && cur->val < cur->next->val;
        if (isMax || isMin) {
            if (first == -1) first = i;
            else minDist = min(minDist, i - prevIdx);
            last = i;
            prevIdx = i;
        }
        prev = cur;
        cur = cur->next;
        i++;
    }
    if (first == last) return {-1, -1};
    return {minDist, last - first};
}
Time: O(n) Space: O(1)