[60天lc] Day4: 24,19,0207,142


24. 两两交换链表中的节点

第一次尝试——失败:

class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next:
            return head
        
        newHead = head
        prev, curr = head, head.next

        while prev and curr:
            nextNode = curr.next
            curr.next = prev
            prev.next = nextNode

            if prev == head:
                newHead = curr

            prev, curr = nextNode, nextNode.next
        
        return newHead

失败原因:

  • 'NoneType' object has no attribute 'next'——需要调整while范围
  • 第二轮交换之后还要将上一轮后一个结点链接到第二轮的第一个结点上 —— 需要fakeHead

第二次尝试——成功:

# 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 swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next:
            return head
        
        fakeHead = ListNode(next=head)
        prev = fakeHead

        while prev.next and prev.next.next:
            # 标记两个需要交换的结点
            curr, post = prev.next, prev.next.next

            # 交换位置
            curr.next = post.next
            post.next = curr
            prev.next = post 

            # 下一个位置
            prev = curr
        
        return fakeHead.next


19. 删除链表的倒数第 N 个结点

第一反应解法:两遍遍历,删除对应结点

class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        # 首先获取正数一共多少个结点
        curr = head
        count = 0
        while curr:
            count += 1
            curr = curr.next
        
        # 判断是否合理的请求
        if n > count:
            return head 
        if n == count:
            return head.next
        
        # 移到倒数第n+1个结点的地方
        t = head 
        for _ in range(count - n - 1):
            t = t.next
        if n == 1:
            t.next = None 
        else:
            t.next = t.next.next
        
        return head

其他解法:

利用栈:

class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        dummy = ListNode(next = head)
        stack = list()
        curr = dummy

        while curr:
            stack.append(curr)
            curr = curr.next
        
        for i in range(n):
            stack.pop()
        
        prev = stack[-1]
        prev.next = prev.next.next

        return dummy.next

只遍历一次解法:

最佳解法——快慢指针:

 

class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        dummyH = ListNode(next = head)
        fast, slow = dummyH, dummyH

        # fast 先走n+1步
        for _ in range(n+1):
            fast = fast.next
        
        # fast,slow一起移动
        while fast:
            slow = slow.next
            fast = fast.next
        
        # 删节点
        slow.next = slow.next.next

        return dummyH.next


面试题 02.07. 链表相交

第一反应解法:利用栈

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        if not headA or not headB:
            return None
        
        stackA, stackB = list(), list()
        currA, currB = headA, headB

        while currA:
            stackA.append(currA)
            currA = currA.next
        while currB:
            stackB.append(currB)
            currB = currB.next
        
        firstInsertNode = None
        while stackA and stackB:
            getA = stackA.pop()
            getB = stackB.pop()
            if getA == getB:
                firstInsertNode = getA 
            else:
                break
            
        return firstInsertNode

比较丑陋的解法。所以去学习了一下其他大神的解法。

优雅解法:双指针【参考Krahets的解法】

Picture1.png

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        pointerA, pointerB = headA, headB
        while pointerA != pointerB:
            pointerA = pointerA.next if pointerA else headB
            pointerB = pointerB.next if pointerB else headA 
        return pointerA

 


142. 环形链表 II 

第一反应解法:字典

class Solution(object):
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head:
            return None 
        dic = dict()
        curr = head 
        index = 0
        while curr:
            if curr in dic.keys():
                return curr
            dic[curr] = index
            curr = curr.next
            index += 1
        
        return None

优雅解法: 双指针【参考Krahets的解法】

class Solution(object):
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        fast, slow = head, head 

        while True:
            if not (fast and fast.next): return 
            fast, slow = fast.next.next, slow.next
            if fast == slow:
                break
        fast = head 
        while fast != slow:
            fast, slow = fast.next, slow.next
        return fast

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值