題意
在 鏈結串列(Linked List) 中, 臨界點(critical point) 被定義為 局部最大值(local maxima) 或 局部最小值(local minima) 。
如果當前節點的值嚴格大於前一個節點和下一個節點,則該節點是 局部最大值(local maxima) 。
如果當前節點的值嚴格小於前一個節點和下一個節點,則該節點是 局部最小值(local minima) 。
但需要注意的是,一個節點只有在存在前一個節點和下一個節點的情況下,才可能是 局部最大值/最小值 。
給定一個 鏈結串列(Linked List) 的頭節點 head \text{head} head ,返回一個長度為2的陣列 [ minDistance , maxDistance ] [\text{minDistance}, \text{maxDistance}] [ minDistance , maxDistance ] ,其中 minDistance \text{minDistance} minDistance 是任意兩個不同臨界點之間的最小距離,maxDistance \text{maxDistance} maxDistance 是任意兩個不同臨界點之間的最大距離。如果臨界點少於2個,則返回 [ − 1 , − 1 ] [-1, -1] [ − 1 , − 1 ] 。
思路:維護第一個和最後一個臨界點的索引
根據題意,我們需要計算臨界點之間的 minDistance \text{minDistance} minDistance 和 m n = maxDistance mn = \text{maxDistance} mn = maxDistance 。而 maxDistance \text{maxDistance} maxDistance 就是第一個和最後一個臨界點之間的距離;而 minDistance \text{minDistance} minDistance 則是任意兩個不同臨界點之間距離的最小距離。因此,我們只需要維護第一個臨界點的索引 first \text{first} first 和最後一個臨界點的索引 last \text{last} last 即可。
令 i d x idx i d x 表示當前節點的索引、p r e pre p re 和 c u r cur c u r 分別指向前一個節點和當前節點。初始化 first \text{first} first 和 last \text{last} last 為 − 1 -1 − 1 ,m n mn mn 為正無窮大。遍歷鏈結串列,若當前節點為臨界點:
如果是第一個臨界點,更新 f i r s t first f i rs t 為當前索引。
否則更新 m n = min ( m n , idx − last ) mn = \min(mn, \text{idx} - \text{last}) mn = min ( mn , idx − last ) 。
然後更新 l a s t last l a s t 為當前索引。
遍歷結束後,若找到了至少兩個臨界點,則返回 [ mn , last − first ] [\text{mn}, \text{last} - \text{first}] [ mn , last − first ] ;否則返回 [ − 1 , − 1 ] [-1, -1] [ − 1 , − 1 ] 。
複雜度分析
時間複雜度:O ( n ) \mathcal{O}(n) O ( n ) ,其中 n n n 為鏈結串列的長度。
空間複雜度:O ( 1 ) \mathcal{O}(1) O ( 1 ) 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution : def nodesBetweenCriticalPoints (self, head: Optional [ListNode] ) -> List [int ]: pre, cur = None , head first = last = -1 mn = float ('inf' ) idx = 0 while cur and cur.next : if pre is not None and (pre.val < cur.val > cur.next .val or pre.val > cur.val < cur.next .val): if first == -1 : first = idx else : mn = min (mn, idx - last) last = idx pre, cur = cur, cur.next idx += 1 return [mn, last - first] if mn != float ('inf' ) else [-1 , -1 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution {public : vector<int > nodesBetweenCriticalPoints (ListNode* head) { ListNode *pre = nullptr , *cur = head; int first = -1 , last = -1 ; int mn = INT_MAX; int idx = 0 ; while (cur && cur->next) { if (pre != nullptr && (pre->val < cur->val && cur->val > cur->next->val || pre->val > cur->val && cur->val < cur->next->val)) { if (first == -1 ) first = idx; else mn = min (mn, idx - last); last = idx; } pre = cur; cur = cur->next; idx++; } return mn != INT_MAX ? vector<int >{mn, last - first} : vector<int >{-1 , -1 }; } };
寫在最後
Cover photo is remixed from @吃肥皂泡泡 , thanks for their work!