1. 程式人生 > >56. Merge Intervals && 57. Insert Interval

56. Merge Intervals && 57. Insert Interval

Merge Intervals

這個簡單,常見的排序合併思路,然後如果前面的end大於當前的start即合併

class Solution(object):
    def merge(self, intervals):
        """
        :type intervals: List[Interval]
        :rtype: List[Interval]
        """
        if len(intervals)==0:return []
        intervals.sort(key=lambda x:x.start)
        ret=[]
        st=intervals[0
].start ed=intervals[0].end for idx in range(1,len(intervals)): if ed >= intervals[idx].start: ed=max(ed,intervals[idx].end) else: ret.append([st,ed]) st=intervals[idx].start ed=intervals[idx].end ret.append([st,ed]) return
ret

Insert Interval

Insert Interval這個做了好久,分了各種情況討論,其實轉換思路成合並區間即可,如果前面的end大於當前的start即合併

 class Solution:
    def insert(self, intervals, newInterval):
        intervals.append(newInterval)
        intervals.sort(key = lambda x:x.start)
        length=len(intervals)
        res=[]
        for
i in range(length): if res==[]: res.append(intervals[i]) else: size=len(res) if res[size-1].start<=intervals[i].start<=res[size-1].end: res[size-1].end=max(intervals[i].end, res[size-1].end) else: res.append(intervals[i]) return res

也可以思路清晰的分情況討論完成。這個分情況那就很多了,橫跨,非常小,最右最左,交叉等等。
對分情況要求很高,思路不清晰能WRONG到死。同時自己寫了個簡單的測試程式

class Solution(object):
    def insert(self, aa, a):
        """
        :type intervals: List[Interval]
        :type newInterval: Interval
        :rtype: List[Interval]
        """
        if len(aa) == 0:
            return [a]
        aa.sort(key=lambda x:x.start)
        st = -1
        for idx,v in enumerate(aa):
            # 完全大於當前無關
            if v.end < a.start:
                continue
            # 完全包含於其他元素無關
            if a.start >= v.start and a.end <= v.end:
                return aa
            # 完全小於當前,則會插入或者合併元素
            if v.start > a.end:
                if st == -1:
                    aa.insert(idx,a)
                else:
                    aa=aa[0:st] + [Interval(min(a.start,aa[st].start),max(a.end,aa[st].end))] + aa[idx:]
                return aa

            if a.start <= v.start and a.end <= v.end:
                if st == -1:
                    aa=aa[0:idx] + [Interval(a.start,v.end)] + aa[idx+1:]
                else:
                    aa=aa[0:st] + [Interval(min(a.start,aa[st].start),max(a.end,v.end))] + aa[idx+1:]
                return aa
            #起點交叉 或者 整個橫跨
            if st == -1 and ((a.start >= v.start and a.end >= v.end) or (a.start <= v.start and a.end >= v.end) ):
                st = idx
            # 交叉情況 第一種是起點交叉(這個要記錄),第二種是終點交叉
            #if v.start <= a.start and v.end >= a.start:
                #st=idx
            # if st==-1 and v.end >= a.start:
            #   st=idx
            # print v,a,st
            # #終點交叉就能夠處理了所以有等號
            # if v.end >= a.end and v.start <= a.end:
            #     # 終點交叉時,起點沒交叉
            #     if st == -1:
            #         aa=[Interval(a.start,v.end)] + aa[idx+1:]
            #     else:
            #         aa=aa[0:st] + [Interval(min(a,start,aa[st].start),max(a.end,v.end))] + aa[idx+1:]
            #     return aa

        #起點有交叉
        if st != -1:
            aa=aa[0:st] + [Interval(min(a.start,aa[st].start),max(aa[st].end,a.end))]
        else:
            # 可能最長
            if aa[0].start > a.start:
                aa=[a]
            else:
                aa.append(a)
        return aa 
def testOne():
    p1=[[0,5],[9,12]]
    p2=[7,16]
    p1,p2=get_input(p1,p2)
    a=Solution().insert(p1,p2)

test_data=[
    ([[1,5]],[0,3]),
    ([[1,2],[3,5],[6,7],[8,10],[12,16]],[4,9]),
    ([[0,5],[9,12]],[7,16]),
    ([[1,3],[6,9]],[2,5]),
    ([[1,5]],[0,6]),
    ([[1,5]],[0,5]),
    ([[1,4],[9,12],[19,22]],[7,13]),
    ([[3,6],[9,9],[11,13],[14,14],[16,19],[20,22],[23,25],[30,34],[41,43],[45,49]],[29,32])
]
stand_data=[
[[0,5]],
[[1,2],[3,10],[12,16]],
[[0,5],[7,16]],
[[1,5],[6,9]],
[[0,6]],
[[0,5]],
[[1,4],[7,13],[19,22]],
[[3,6],[9,9],[11,13],[14,14],[16,19],[20,22],[23,25],[29,34],[41,43],[45,49]],
]

a=map(lambda x:Solution().insert(x[0],x[1]),map(lambda x:get_input(x[0],x[1]),test_data))
#print a
#print cmp(a,stand_data)
for l1,l2 in zip(stand_data,a):
    #print l1,'==>',l2
    l1 = ('%s'%l1).replace(' ','')
    l2 = ('%s'%l2).replace(' ','')
    #print l1,l2
    if l1!=l2:
        print l1,'==>',l2