路标插入间隔问题
問題描述:
有一段長度為N的路,有m個路標,用整數數組表示。m個路標是無序的。求每次插入m中一個路標后,求最長沒有路標的路徑為多長。
輸入:
N,m --> [2, 30, 25, 90, 17]
輸出:
m 長度數組 [98, ...] 表示,插入第一個路標后,最長的沒有路燈的長度。
思路1:
當m個路標可以同時提供的情況下,可以逆向思考這個問題。
首先對m個路標排序,得到 [2, 17, 25, 30, 90],這個時候最大的沒有路燈的間隔是 max_range=59 (90-30-1)
我們可以按照, 原始的順序的逆序,一次刪除路標。
比如首先刪除17, 那么排序后的序列變為 [2, 25, 30, 90], 刪除17得到新的區間是 [2, 25], 其長度小于 max_range, 因此選擇不更新,max_range。
數據結構:
考慮到O(1)的訪問復雜度,和O(1)區間刪除合并操作,顯然鏈表和數組滿足不了這個要求。
因此可以使用 哈希表 + 鏈表結合的方式解決這個問題。
具體設計為
{ location_mark: [left_mark, right_mark], ... }思路2:
上述設計的方法有一定的局限性,如果路標只能逐個提供,并要求必須返回,那么思路1就無法解決。
首先為了維護,區間分割的結構,可以選擇二叉樹
? ? ? ? ? ? ? ? Node(1, N)
? ? ? ? /? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
? ? ?/? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
Node(1, Split_1)? ?Node(Split_1, N)
這樣,每次插入新的切割點,復雜度是O(log(n))。
為了在O(1)復雜度內返回最長的間隔,可以在Node加入max_length值,維護某個范圍內的最大長度。
具體代碼為:
typedef struct Node {Node* l, r;int s, e, len; } Node;Node* new_node(int s, int e) {Node* ret = new Node();ret->l = nullptr;ret->r = nullptr;ret->s = s;ret->e = e;ret->len = e - s + 1;return ret; }int solve_once(Node* root, int new_split) {if (root->l == nullptr) {root->l = new_node(root->s, new_split-1);root->r = new_node(new_split+1, root->e);return max(root->l->len, root->r->len);}// select one branchif (new_split >= root->l->s && new_split <= root->l->e) {root->len = max(root->len, solve_once(root->l, new_split));}if (new_split >= root->r->s && new_split <= root->r->e) {root->len = max(root->len, solve_once(root->r, new_split));}return root->len; }總結
- 上一篇: 在PSP上玩《大旋风 Twin Hawk
- 下一篇: Go程序实例分析