Leetcode: Linked List

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

206 Reverse Linked List

class Solution:
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        cur, pre = head, None
        while cur:
            # 反转后, 更新pre指针
            cur.next, pre, cur = pre, cur, cur.next
        return pre

24 Swap Nodes in Pairs

class Solution:
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        pre, pre.next = self, head
        while pre.next and pre.next.next:
            a = pre.next
            b = a.next
      		# 三个节点进行交换: pre->a->b->c, pre->b->a->c
            pre.next, b.next, a.next = b, a, b.next
            # 更新pre指针位置
            pre = pre.next.next

        return self.next

141 Linked List Cycle

  • 法一:用集合记录每个节点的值,同时进行查重。O(n)的空间时间复杂度
class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        # init
        d = set()
        p = head
        while p and p.next:
            if p not in d: # search
                d.add(p) # insertion
                p = p.next # move
            else:
                return True
        return False
  • 法二:双指针,两个指针移动速度一快一慢。O(1)的空间复杂度,O(N)的时间复杂度
class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
		slow = fast = head
        while fast and fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True
        return False

142 Linked List Cycle II

同上两种方法,其中双指针方法,多画画图就能发现个规律:迭代次数等于环节点数。因此这里可以知道头结点到环入口等于相遇点再次到达环入口,利用这个等式可以知道求解该题

class Solution(object):
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        # set method
        d = set()
        p = head
        while p:
            if p not in d:
                d.add(p)
                p = p.next
            else:
                return p         
        return None
class Solution(object):
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        # two pointer
        slow = fast = head   
        while fast and fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
            # 如果相遇,慢指针从头走,快指针以1为步长继续走,相遇时即为环入口
            if slow == fast:
                slow = head
                while slow != fast:
                    slow = slow.next
                    fast = fast.next
                return slow
        return None

25 Reverse Nodes in k-Group

class Solution:
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        pre, pre.next = self, head
        while 1:
            # 这里用一个常数k的额外空间来记录
            temp = []            
            for i in range(k):
                temp.append(pre.next)
                if pre.next == None:
                    pre.next = temp[0]
                    return self.next
                pre.next = pre.next.next
            # pre.next = head
            # exchange node
            tempp = temp[-1].next # 临时记录下一个节点的地址
            pre.next = temp[-1] # 把最后一个节点放在最开始
            for i in range(k-1,0,-1): # 中间的节点依次换方向
                temp[i].next = temp[i-1]
            temp[0].next = tempp # 指向第20行记录的地址
            # move pre
            for i in range(k):
                pre = pre.next

总结一下:链表的题,通常搞定一组操作后就是while到表尾。应该注意边界问题,有些问题有点绕,链来链去的,求解时可以把头几次的迭代画出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值