代码随想录算法训练营第四天 | 24 两两交换链表、19删除链表的倒数第几、面试题 02.07. 链表相交、142.环形链表II

24 两两交换链表

题目链接:

代码随想录_两两交换链表

自己想

1.首先明确交换的抽象就是将当前节点指针指向前一个节点,
2.确定好循环体内的步骤,即每一次要完成哪几步
3.确定好边界条件

看完题解

1.首先就是要引入虚拟头节点cur = new_node(next=head)
2.交换,需要存储一个中间变量,temp = cur.next。交换完毕之后还需要将虚拟头节点移动到cur.next.next。这样又可以开始一次循环,也就是说每一个循环内要完成三个操作:
3.根据上述要完成的操作,可以明确,不仅要找到虚拟头节点的next不为空,还需要保证next.next不为空,因此while(cur.next and cur.next.next)

完整代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        new_node = ListNode(next = head)

        cur = new_node
        if (cur.next is not None) and (cur.next.next is not None):
            while((cur.next is not None) and (cur.next.next is not None)):
                temp1 = cur.next
                temp2 = cur.next.next.next
                cur.next = cur.next.next
                cur.next.next = temp1
                temp1.next = temp2
                cur = temp1

            return new_node.next
            
        else:
            return new_node.next
        

19 删除链表的倒数第n

题目链接:

代码随想录_删除链表中倒数第n

自己想

1.如果线性思考,删除倒数,不仅需要知道链表长度,就需要遍历到尾,然后再遍历一遍找到倒数的n,如何用更好的方法呢?自己没想到
2.删除就是将待删除的节点
3.确定好边界条件是什么呢?

看完题解

1.首先就是要引入虚拟头节点cur = new_node(next=head),为了删除某一个节点,要找到这个节点的前一个节点才行
2.删除使用双指针,双指针间隔为n,这样就能找到了
3.边界条件就是,快指针对应的下一个指针为空指针即可

关键思路衔接

写这个的目的就是以前关键点思路清楚了,但是到具体实现,衔接关键点就会混乱,具体的混乱体现在while,if设置不清楚。
1.为了使快慢指针间隔为n(为的是当快指针在末尾时,慢指针在要删除节点的前一个节点),那么也就是让快指针先走n步,其实就可以先一个while循环,让快指针走到第n步;然后再写一个while(fast)

完整代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:

        # new_node = ListNode(next = head)
        # cur = new_node
        # cur1 = new_node
        # n1 = 0
        # while(cur1):
        #     cur1 = cur1.next
        #     n1 += 1
        # n2 = n1-n
        # if (cur.next is not None):
        #     while(n2 - 1):
        #         cur = cur.next
        #         n2 -= 1
            
        #     cur.next = cur.next.next

        #     return new_node.next

        # else: return new_node.next

        #双指针
        new_node = ListNode(next = head)
        fast = new_node
        low = new_node
        n1 = 0
        while(fast.next is not None):
            fast = fast.next
            print(fast)
            n1 += 1
            if n1 >= n +1:
                low = low.next
                print(low)

            
        low.next = low.next.next

        return new_node.next





面试题 02.07. 链表相交

题目链接:

代码随想录_链表相交

自己想

1.链表都不一样长,怎么判断呢?然后就进行不下去了
2.确定好循环体内的步骤,即每一次要完成哪几步
3.确定好边界条件

看完题解(关键思路

1.判断相交,求出A链表与B链表的长度,然后求出差值,先让长链表先走n步,之后两个链表一起前进,当链表A,Bd的下一个指针相等时,即为相交点

思路衔接及细节

并不确定链表A,B那一个长,需要加一个判断条件去更改

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

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        #求得链表1和链表2的长度
        cur1 = headA
        cur2 = headB
        n1,n2 = 0,0
        while(cur1):
            cur1 = cur1.next
            n1 += 1
        while(cur2):
            cur2 = cur2.next
            n2 += 1
        # 判断一下长度,让curA一直为最长
        cur1 = headA
        cur2 = headB
        if n2 > n1:
            n1,n2 = n2,n1
            cur1,cur2 = cur2,cur1
        diff_ = n1 - n2
        while(diff_):
            cur1 = cur1.next
            diff_ -= 1
        while(cur2):
            if cur2 == cur1:
                return cur2
            else:
                cur1 = cur1.next
                cur2 = cur2.next
            
        
        return None    

142.环形链表II

题目链接:

代码随想录_环形链表

自己想

1.如何判断有环,我想的应该就是cur.next一直不为空就可以
2.如何判断环的起点
3.确定好边界条件

看完题解(关键思路

1.判断有环也是定义快慢指针,如果快慢指针相遇即有环
2.判断环的起点是运用了数学知识,假设相遇点,然后找到条件,下图来自代码随想录_环形链表
在这里插入图片描述

具体就是x = z,利用这个条件去找环入口

思路衔接及细节

因为fast要一次走两步,所以第一个while(fast.next.next),在此循环里,当if fast==low:设置两个指针利用x=z去寻找对应环入口,在if中还有while(index != index1):

完整代码
class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        
        fast = head
        low = head
        while(fast  and fast.next):#
            fast = fast.next.next 
            low = low.next
            if fast == low:
                
                index = head
                index1 = fast
                while(index != index1):
                    index = index.next
                    index1 = index1.next
                
                return index
            

        return None

收获

1.加深了双指针的应用,在链表相关的题中,要学会使用双指针,例如删除这一操作,在数组和链表中都使用了双指针
2.虚拟头节点的使用,例如在删除链表都一个节点时,要考虑节点的上一个节点,就要想到使用虚拟头节点
3.思路链接性,while,if 懂不懂就搞混,要注意!!!如何明确什么时候用if和while

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值