leetcode每周3道(二)

 56. 合并区间

思路:

(1)排序+双指针

不断判断left,right,next_left,next_right之间的关系,先sort一下使得next_left一定大于now_left。那么就只要判断以下情况,并做各自的处理。

时:O(nlogn) 空:O(nlogn) 

class Solution(object):
    def merge(self, intervals):
        """
        :type intervals: List[List[int]]
        :rtype: List[List[int]]
        """
        l = len(intervals)
        if l == 1:
            return intervals
        ans = []
        intervals.sort()
        left = intervals[0][0]
        right = intervals[0][1]
        for i in range(1,l):
            next_left = intervals[i][0]
            next_right = intervals[i][1]
            if next_left > right:
                ans.append([left, right])
                left = next_left
                right = next_right
            else:
                if next_right > right:
                    right = next_right
            if i == l-1:               #注意判断到最后一个区间时要单独处理一下。
                ans.append([left,right])
        return ans

(2)排序+两两合并

同样先把数组按照left排序,然后就只需判断next_left、next_right与now_right之间的大小关系即可。如果next_left>now_right就把下一个区间append进答案数组;否则的话就判断next_right和now_right,如果next_right大就把now_right更新为next_right。

class Solution(object):
    def merge(self, intervals):
        """
        :type intervals: List[List[int]]
        :rtype: List[List[int]]
        """
        intervals.sort()
        ans = []
        ans.append(intervals[0])
        l = len(intervals)
        for next_ in intervals[1:]:
            if next_[0] > ans[-1][1]:#下一个区间的左端点>当前区间右端点直接加入答案
                ans.append(next_)
            else:
                ans[-1][1] = max(ans[-1][1],next_[1])#下一个区间的左端点<=当前区间右端点就说明可以合并,判断下一个区间的右端点和当前区间的右端点哪个大以进行合并。
        return ans

 

 148. 排序链表

思路:

1、额外数组

(1)链表存入数组,数组排序后,按顺序修改链表结点的值。时:O(nlogn) 空:O(n)

(2)额外数组也可以不用排序,而是记录一下当前数的个数,这样就可以重建一个链表,返回这个链表的头结点。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        ans = []
        index = head
        while index:
            ans.append(index.val)
            index = index.next
        ans.sort()
        index = head
        for i in ans:
            index.val = i
            index = index.next
        return head

 

 2、归并排序

首先要切分链表、写好merge函数,再用递归实现归并。时:O(nlogn) 空:O(logn)

每次把链表切分一半,找到中点。递归切分,最后再递归中逐层merge。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        def find_mid(head):                #把链表拆成2部分,分别返回两部分的头结点
            fast = slow = head
            while fast.next and fast.next.next:
                fast = fast.next.next
                slow = slow.next
            tmp = slow.next
            slow.next = None
            return head,tmp

        def merge(head1,head2):            #合并2个有序数组
            if not (head1 and head2):
                if not head1:
                    return head2
                else:
                    return head1
            dummy = ListNode(-1)
            pre = dummy
            while head1 and head2:
                if head1.val < head2.val:
                    pre.next = head1
                    head1 = head1.next
                else:
                    pre.next = head2
                    head2 = head2.next
                pre = pre.next
            if head1:
                pre.next = head1
            if head2:
                pre.next = head2
            return dummy.next

        def sort_fun(head):               #递归实现不断拆分合并
            if not head or not head.next:
                return head
            first, second = find_mid(head)
            return merge(sort_fun(first),sort_fun(second))

        return sort_fun(head)

 3、自底向上的归并排序

时:O(nlogn) 空:O(1)

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        dummy = ListNode(-1)
        dummy.next = head
        tmp = head
        length = 0
        while tmp:
            length += 1
            tmp = tmp.next
        step = 1
        while step < length:
            cur = dummy.next        #下一组没有处理的头结点
            tail = dummy            #上一组处理好的头结点
            while cur:
                left = cur          
                right = self.cut(cur,step)
                cur = self.cut(right,step)    #更新没处理的头结点
                tail.next = self.merge(left, right)      #把处理好的挂到末尾
                while tail.next:                      #更新处理好的尾结点
                    tail = tail.next
            step <<= 1                 #注意左移1位不是2位,用不好别用
        return dummy.next


    def cut(self, head, size):
        size -= 1#为了保存前一个结点
        while head and size:
            head = head.next
            size -= 1
        if not head:#可能出现不够size的情况
            return None 
        tmp = head.next 
        head.next = None
        return tmp

    def merge(self, head1, head2):
        if not (head1 and head2):
            if not head1:
                return head2
            else:
                   return head1
        dummy = ListNode(-1)
        pre = dummy
        while head1 and head2:
            if head1.val < head2.val:
                pre.next = head1
                head1 = head1.next
            else:
                pre.next = head2
                head2 = head2.next
            pre = pre.next
        if head1:
            pre.next = head1
        if head2:
            pre.next = head2
        return dummy.next

274. H 指数 

思路

理解题意需要一会,自己举几个例子就明白了,发现降序排列后,只有citations[i]的值比i+1的大或者相等的时候才满足,如果citations[i]<i+1那就不满足了,h最大就是i+1了。

1、 排列+查找

先降序排列,再顺序查找什么时候不符合题意就break,返回ans。时O(nlogn) 空O(nlogn)都是排序的复杂度。

class Solution(object):
    def hIndex(self, citations):
        """
        :type citations: List[int]
        :rtype: int
        """
        citations.sort(reverse = True)
        ans = 0
        for i, num in enumerate(citations):
            if num < i+1:
                break
            ans+=1
        return ans

 2、计数排序

开辟一个数组用来记录当前引用次数的论文有几篇。根据定义,H 指数不可能大于总的论文发表数,所以对于引用次数超过论文发表数的情况,可以将其按照总的论文发表数来计算即可。

这样就限制了参与排序的数的大小为[0,n](其中 n 为总的论文发表数),使得计数排序的时间复杂度降低到 O(n)。最后从后向前遍历数组 ,对于每个0≤i≤n,在数组r 中得到大于或等于当前引用次数 i 的总论文数。当找到一个 H 指数时跳出循环,并返回结果。

时O(n) 空O(n)

class Solution(object):
    def hIndex(self, citations):
        """
        :type citations: List[int]
        :rtype: int
        """
        length = len(citations)
        arr = [0]*(length+1)
        ans = 0
        for i,num in enumerate(citations):
            if num>=length:
                arr[length] += 1
            else:
                arr[num] += 1
        for i in range(length,-1,-1):
            ans += arr[i]
            if ans>=i:
                return i
        return 0

3、二分查找

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值