
Problem Statement
In a linked list, a critical point is defined as a node which is either a local maxima or a local minima. Understanding these terms:
- A node is a local maxima if its value is strictly greater than those of its neighbouring nodes (both previous and next).
- A node is a local minima if its value is strictly less than those of its neighbouring nodes (both previous and next).
For a node to qualify as a local maximum or minimum, it must have both a predecessor and a successor in the linked list.
The task is to return an array of two integers, [minDistance, maxDistance]
, based on the critical points found in the given linked list head
:
minDistance
is the smallest distance between any two critical points.maxDistance
is the largest distance between any two critical points.
If fewer than two critical points exist in the linked list, the function should return [-1, -1]
.
Examples
Example 1
Input:
head = [3,1]
Output:
[-1,-1]
Explanation:
There are no critical points in [3,1].
Example 2
Input:
head = [5,3,1,2,5,1,2]
Output:
[1,3]
Explanation:
There are three critical points: - The third node is a local minima because 1 is less than 3 and 2. - The fifth node is a local maxima because 5 is greater than 2 and 1. - The sixth node is a local minima because 1 is less than 5 and 2. The minimum distance is between the fifth and the sixth node: 6 - 5 = 1. The maximum distance is between the third and the sixth node: 6 - 3 = 3.
Example 3
Input:
head = [1,3,2,2,3,2,2,2,7]
Output:
[3,3]
Explanation:
There are two critical points: - The second node is a local maxima because 3 is greater than 1 and 2. - The fifth node is a local maxima because 3 is greater than 2 and 2. Both the minimum and maximum distances are between the second and the fifth node: 5 - 2 = 3.
Constraints
- The number of nodes in the list is in the range
[2, 10^5]
1 <= Node.val <= 10^5
Approach and Intuition
To solve this problem, follow these stages:
Traverse the Linked List:
- Keep track of each node’s index.
- For each node (excluding the first and last), check if it is a local maxima or minima by comparing it with its previous and next node values.
Store Indices of Critical Points:
- Add the index of each detected critical point into a list.
Check Critical Point Count:
- If fewer than two critical points are found, return
[-1, -1]
.
- If fewer than two critical points are found, return
Compute Distances:
maxDistance
= difference between the first and last critical point indices.minDistance
= smallest difference between any two consecutive critical point indices.
This method ensures an O(n) traversal and calculation, which is optimal for the problem's constraints.
Solutions
- C++
- Java
- Python
class Solution {
public:
vector<int> criticalPointsDistance(ListNode* head) {
vector<int> distances = {-1, -1};
// Maximum value for minimizing
int minimumInterval = INT_MAX;
// Setup for current, previous node tracking
ListNode* prev = head;
ListNode* curr = head->next;
int idxCurr = 1;
int idxPrevCritical = 0;
int idxFirstCritical = 0;
// Iterate through list
while (curr->next != nullptr) {
// Determine if there's a critical point
if ((curr->val > prev->val && curr->val > curr->next->val) ||
(curr->val < prev->val && curr->val < curr->next->val)) {
// Handle the first found critical point
if (idxPrevCritical == 0) {
idxPrevCritical = idxCurr;
idxFirstCritical = idxCurr;
} else {
// Update minimum interval and previous index
minimumInterval = min(minimumInterval, idxCurr - idxPrevCritical);
idxPrevCritical = idxCurr;
}
}
// Advance pointers
++idxCurr;
prev = curr;
curr = curr->next;
}
// Resolve the results if more than one critical point exists
if (minimumInterval != INT_MAX) {
int maxInterval = idxPrevCritical - idxFirstCritical;
distances = {minimumInterval, maxInterval};
}
return distances;
}
};
This C++ solution finds the minimum and maximum number of nodes between critical points in a linked list. Critical points are nodes where the value is either greater than or less than both its adjacent values. Here's how the solution is implemented:
Initialize a
vector
calleddistances
with values-1, -1
to hold the minimum and maximum intervals between critical points. If there are less than two critical points, the vector remains as-1, -1
.Utilize two pointers,
prev
andcurr
, to traverse the linked list from the first node. Also maintainidxCurr
to keep track of the current node index.For each node in the list (except the first and last), check if it is a critical point. A node is considered as a critical point if:
- It is greater than both its previous and next nodes.
- It is less than both its previous and next nodes.
If the current node is a critical point and is the first critical point found, store its index in both
idxPrevCritical
andidxFirstCritical
.If another critical point is identified, update the
minimumInterval
by calculating the difference between the current index and the last previous critical index. UpdateidxPrevCritical
with the current index.Continue this until the end of the list is reached.
After the traversal, if at least two critical points were found (i.e.,
minimumInterval
is notINT_MAX
), calculate themaxInterval
as the difference between the last and first critical indices and update thedistances
with both the minimum and maximum intervals.Finally, return the
distances
vector containing the minimum and maximum intervals between critical points if they exist. If there are less than two critical points, it will return-1, -1
indicating no intervals can be determined.
This solution efficiently identifies critical points and measures the intervals by iterating through the linked list once, ensuring a time complexity of O(n), where n is the number of nodes in the list.
class Solution {
public int[] criticalDistance(ListNode head) {
int[] distance = { -1, -1 };
// Minimum distance initialized to a large number
int minDist = Integer.MAX_VALUE;
// Position markers and previous critical point data
ListNode prevNode = head;
ListNode currNode = head.next;
int currIndex = 1;
int lastCritIndex = 0;
int firstCritIndex = 0;
while (currNode.next != null) {
// Determine if current node is a critical point
if (
(currNode.val < prevNode.val && currNode.val < currNode.next.val) ||
(currNode.val > prevNode.val && currNode.val > currNode.next.val)
) {
// Handle first critical point found
if (lastCritIndex == 0) {
lastCritIndex = currIndex;
firstCritIndex = currIndex;
} else {
// Update minimum distance
minDist = Math.min(
minDist,
currIndex - lastCritIndex
);
lastCritIndex = currIndex;
}
}
// Progress the pointers
currIndex++;
prevNode = currNode;
currNode = currNode.next;
}
// Check if enough critical points were found
if (minDist != Integer.MAX_VALUE) {
int maxDist = lastCritIndex - firstCritIndex;
distance = new int[] { minDist, maxDist };
}
return distance;
}
}
To find the minimum and maximum number of nodes between critical points in a linked list, follow these steps in Java:
- Initialize a
distance
array to{-1, -1}
to store the results. If no critical point pairs are found, this will be the result returned. - Set
minDist
toInteger.MAX_VALUE
to track the smallest distance encountered. - Use nodes
prevNode
andcurrNode
to iterate through the list starting from the head. UsecurrIndex
to track the current node's index. - Initialize
lastCritIndex
andfirstCritIndex
to0
to record indices of critical points. - Process each node until the end of the list (
currNode.next != null
):- Check if a node is a critical point by comparing its value with its neighbors. This includes:
- A node having a value less than both of its neighbors.
- A node having a value greater than both of its neighbors.
- If
lastCritIndex
is0
(no critical points found yet), setlastCritIndex
andfirstCritIndex
to the current index. - If it's not the first critical point, calculate the distance from the last critical point and update
minDist
if the current distance is smaller. - Move
lastCritIndex
to the current index. - Increment
currIndex
and progressprevNode
andcurrNode
.
- Check if a node is a critical point by comparing its value with its neighbors. This includes:
- After exiting the loop, check if
minDist
was updated:- Calculate the maximum distance (
maxDist
) as the difference between the last and first critical indices. - Set
distance
array to{ minDist, maxDist }
.
- Calculate the maximum distance (
- Return the
distance
array containing the minimum and maximum distances between critical points. If no critical point pairs are found, the method returns{-1, -1}
.
Ensure your linked list contains enough nodes to correctly detect critical points and calculate distances. The above approach provides an efficient method to tackle the problem within a single traversal of the linked list.
class Solution:
def criticalPointsDistance(self, head: Optional[ListNode]) -> List[int]:
output = [-1, -1]
minimum_gap = float("inf")
# Setup to navigate the linked list
prev = head
current = head.next
index = 1
first_crit = 0
last_crit = 0
while current.next is not None:
if (
current.val < prev.val and current.val < current.next.val
) or (
current.val > prev.val and current.val > current.next.val
):
# Determine distances when a critical point is found
if last_crit == 0:
last_crit = index
first_crit = index
else:
minimum_gap = min(minimum_gap, index - last_crit)
last_crit = index
# Move pointers and index forward
index += 1
prev = current
current = current.next
if minimum_gap != float("inf"):
maximum_gap = last_crit - first_crit
output = [minimum_gap, maximum_gap]
return output
The provided Python code defines a method criticalPointsDistance
in the Solution
class for finding the minimum and maximum number of nodes between critical points in a linked list. Here is a summary of how this solution works:
Initialize the output list with
[-1, -1]
to handle cases where there are no valid critical points.minimum_gap
is set to infinity to find the minimum distance effectively when encountered.Use pointers,
prev
andcurrent
, to traverse the linked list. Start from the second node because critical points are related to its adjacent nodes.Initialize
index
to track the current node's position andfirst_crit
andlast_crit
to store the positions of the first and last critical points found.Loop through the nodes until the second last node (
current.next
is notNone
).Check if the current node is a critical point by comparing its value with the adjacent nodes. A node is considered critical if
- It is a peak (greater than both its neighbors).
- It is a valley (smaller than both its neighbors).
If a critical point is found and
last_crit
is zero (indicating the first critical point):- Set
last_crit
andfirst_crit
to the current index. - Else, update
minimum_gap
with the difference between theindex
of the current critical point and theindex
of the last critical point, and updatelast_crit
to the current index.
- Set
After the loop, if
minimum_gap
is less than infinity (indicating that more than one critical point was found):- Calculate
maximum_gap
as the distance between the first and last critical points. - Update the
output
with[minimum_gap, maximum_gap]
.
- Calculate
Return the
output
, which contains the minimum and maximum gaps between critical points if at least two critical points are found, or[-1, -1]
if fewer than two critical points exist.
This solution essentially scans through the linked list to detect critical points and captures their distances to determine the required minimum and maximum gaps.
No comments yet.