【LeetCode】57. Insert Interval 插入序列

一、概述

輸入一個元素爲子區間的長序列和一個目標區間,將目標區間插入到長序列中。注意長序列中各元素不重疊,要求插入後不破壞不重疊這一性質。舉例如下:

長序列爲[[1,2],[3,5],[6,7],[8,10],[12,16]],目標區間爲[4,8],要求不重疊,則插入後的長序列爲[[1,2],[3,10],[12,16]]。

這道題與第56題相關,最簡單的做法是把目標序列push進長序列,然後sort,化爲56題做。但是很麻煩,時間複雜度O(nlogn)。我的方法時間複雜度爲O(n)。

二、分析

題目很直觀,總的來說就是在子區間中找到目標區間左端點left和右端點right的位置,我們維護兩個變量now_min和now_max記錄位置:

先找左端點的位置:

從頭開始遍歷整個序列,找到第一個子區間n,它的右端點值大於等於left,則left位置一定在n-1的右端點到n的右端點這部分區間內,即now_min可能取值爲n的左端點,此時n的左端點值小於left;或取值爲left,此時n的左端點值大於left。

然後找右端點的位置:

右端點可能落在子區間之內,也可以落在子區間之間,因此都需要注意:以n爲第一個區間,以n的右端點到n+1的左端點爲第二個區間;以此類推。在具體實現時,首先判斷第i個區間,然後判斷第i個區間和第i+1個區間之間的區間。當right落在區間內時,now_max取值爲區間右端點;當right落在區間之間時,now_max取值爲right。

當now_min和now_max取值完畢,push到res中,之後使用insert將原序列後面的元素插入res的後面即可。

代碼如下:

class Solution {
public:
    vector<vector<int>> insert(vector<vector<int>>& inter, vector<int>& newInter) {
        vector<vector<int>> res;
        if(inter.size()==0)
        {
            res.push_back(newInter);
            return res;
        }
        for(int i=0;i<inter.size();++i)
        {
            if(inter[i][1]<newInter[0])
            {
                res.push_back(inter[i]);
            }
            else
            {
                int now_min=-1;
                if(inter[i][0]<newInter[0])
                    now_min=inter[i][0];
                else
                    now_min=newInter[0];
                int now_max=-1;
                if(inter[i][0]>newInter[1])
                    now_max=newInter[1];
                else
                {
                    for(;i<inter.size();++i)
                    {
                        if(inter[i][0]<=newInter[1]&&inter[i][1]>=newInter[1])
                        {
                            now_max=inter[i][1];
                            break;
                        }
                        if(i==inter.size()-1||(inter[i][1]<=newInter[1]&&inter[i+1][0]>newInter[1]))
                        {
                            now_max=newInter[1];
                            break;
                        }
                    }
                    ++i;
                }
                vector<int> tmp;
                tmp.push_back(now_min);
                tmp.push_back(now_max);
                res.push_back(tmp);
                res.insert(res.end(),inter.begin()+i,inter.end());
                return res;
            }    
        }
        res.push_back(newInter);
        return res;
    }
};

三、總結

雙指針法一直是很好用的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章