测开准备-day04数据结构力扣

本来应该周六写的,结果放到今天了,还是链表的相关题目。

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

题目链接24. 两两交换链表中的节点 - 力扣(LeetCode)

思路

还是要用虚拟头结点,然后他的这个转换过程我画了一个图

上面那个图是交换之前,虚线是交换位置的操作。下面那个图是交换之后

cur需要指向需要翻转节点的前一位,比如这里,交换1,2节点,这时候cur是指向的虚拟头结点。

伪代码

python 复制代码
dummyhead->next=head
cur=dummyhead
while(cur->next != Null && cur->next->next!=Null):
    //节点数目为偶数cur->next为空的时候结束,节点数目为奇数cur->next->next为空时结束
//先写cur->next,再写cur->next->next否则可能报空指针异常
    temp=cur->next//记录节点1
    temp1=cur->next->next->next//记录节点3
    cur->next=cur->next->next//虚拟头结点指向2
//接下来应该2指向1,但是1找不到了,所以需要记录节点1
//同时如果2指向1,那节点3也找不到了,还要记录节点2
    cur->next->next=temp//节点2指向节点1
    temp->next=temp1//节点1指向节点3
    cur=cur->next->next
return dummyhead->next
  

怎么处处是陷阱,很多需要注意的地方。

写题

报错

1.循环条件这里要写and

python 复制代码
        while(cur.next and cur.next.next):

2.运行超时

是我忘记移动cur指针

python 复制代码
            cur=cur.next.next

但是都比较快的反应过来,所以没有单独截报错的图

提交通过

python 复制代码
# 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]:
        dummy=ListNode(0)
        dummy.next=head
        cur=dummy
        while(cur.next and cur.next.next):
            temp1=cur.next
            temp3=cur.next.next.next
            cur.next=cur.next.next
            cur.next.next=temp1
            temp1.next=temp3
            cur=cur.next.next
        return dummy.next

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

题目链接19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

思路

刚开始看到这个题,感觉可以用快慢指针,但是写出来还是报错。就是边界问题处理的不行,另外代码其他地方有没有问题我也不知道

然后我还是去看了一下讲解

喔他还是快慢指针,但是和我的不一样,是让fast先走n+1步,然后fast和slow一起同速度移动,直到fast的next为空,slow指向需要删除节点的前一个。

伪代码

python 复制代码
fast=dummyhead
slow=dummyhead
n=n+1
while(n-- && fast!=Null):
    fast=fast->next
while(fast!=Null):
    fast=fast->next
    slow=slow->next
slow->next=slow->next->next
return dummyhead.next

写题

python 复制代码
# 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]:
        dummy=ListNode(0)
        dummy.next=head
        fast=dummy
        slow=dummy
        while(n+1 and fast!=None):
            fast=fast.next
            n=n-1
        while(fast):
            fast=fast.next
            slow=slow.next
        slow.next=slow.next.next
        return dummy.next

修改

1.之前走n步,现在改为n+1步,slow在需要删除节点的前一个

2.第一个while循环里面加入判断fast!=None这个条件,防止空指针

160.链表相交

题目链接160. 相交链表 - 力扣(LeetCode)

思路

好像也是快慢指针,然后中间有一些数学知识,但是我第一次做题的时候没看懂

一、核心思路

我们可以用双指针法,这是最简单高效的解法,时间复杂度 O (n+m),空间复杂度 O (1):

  1. 用两个指针 pApB 分别从 headAheadB 出发,各自遍历链表。

  2. pA 走到链表 A 的末尾时,让它从链表 B 的头部重新开始走;当 pB 走到链表 B 的末尾时,让它从链表 A 的头部重新开始走。

  3. 这样两个指针最终会在相交节点 相遇(如果存在相交),或者同时走到 null(如果不相交)。

为什么这样能找到交点?

  • 假设链表 A 长度为 a,链表 B 长度为 b,公共部分长度为 c

  • 指针 pA 走的总路程:a + c + b

  • 指针 pB 走的总路程:b + c + a

  • 两者路程相等,所以一定会在交点处相遇。

?记忆中是比较复杂的,但是现在看来还是可以理解。

伪代码

python 复制代码
函数 getIntersectionNode(headA, headB):
    如果 headA 为空 或者 headB 为空:
        返回 null

    初始化 pA = headA
    初始化 pB = headB

    当 pA != pB:
        如果 pA 不为空:
            pA = pA.next  # 继续走A链表
        否则:
            pA = headB    # 走到A末尾,切换到B链表开头

        如果 pB 不为空:
            pB = pB.next  # 继续走B链表
        否则:
            pB = headA    # 走到B末尾,切换到A链表开头

    返回 pA  # 此时pA和pB同时指向交点或null

写题

python 复制代码
# 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) -> Optional[ListNode]:
        pa=headA
        pb=headB
        while(pa != pb):
            if pa!= None:
                pa=pa.next
            else:
                pa=headB
            if pb!=None:
                pb=pb.next
            else:
                pb=headA
        return pa

142.环形链表||

题目链接142. 环形链表 II - 力扣(LeetCode)

思路

需要得到两个东西,1.是否有环,2.环的入口节点

1.判断是否有环

快指针,每次走两个节点

慢指针,每次走一个节点

如果他们两个相遇,那就是有环

为什么他们两个不会错过?快指针每次比慢指针多走一个,不会错过。

2.环的入口节点

原来是这个,之前说那个比较复杂的推导。红笔是标的走的方向,x,y,x是标的路程

定义a是头结点,b是快慢指针相遇的点,a,b以相同速度走,会在入口处相遇

python 复制代码
fast=head
slow=head
while fast!=None && fast->next!=Null://快指针走在前面,只需要判断他。
//因为快指针一次走两步,所以还要判断fast->next
    fast=fast->next->next
    slow=slow->next
    if fast==slow:
        index1=fast
        index2=head
        while(index1!=index2):
            index1=index1->next
            index2=index2->next
        return index1
return Null

写题

报错1

是我返回值的位置写错了

提交

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

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        fast=head
        slow=head
        while(fast!=None and fast.next !=None):
            fast=fast.next.next
            slow=slow.next
            if fast==slow:
                index1=head
                index2=fast
                while(index1!=index2):
                    index1=index1.next
                    index2=index2.next
                return index1
        return None

我的感悟:每道题都有自己的花招,虽然说有些能大概知道是快慢指针,但是具体快多少,条件怎么判断,都是需要仔细去写的。

相关推荐
千码君20162 小时前
kotlin:函数式参数
java·算法·kotlin
2401_833197732 小时前
现代C++多线程编程实战
开发语言·c++·算法
m0_587958952 小时前
C++中的适配器模式实战
开发语言·c++·算法
sprite_雪碧2 小时前
3.2 最大公约数(GCD)&斐波那契数列 & 素数相关(机试高频数学考点)
算法
2301_776508722 小时前
C++中的职责链模式实战
开发语言·c++·算法
sqyno1sky2 小时前
C++中的空对象模式
开发语言·c++·算法
yunyun321232 小时前
动态库热加载技术
开发语言·c++·算法
88号技师2 小时前
2026年3月一区SCI-B样条曲线优化算法B-spline curves optimizer-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法
dapeng28702 小时前
C++中的享元模式实战
开发语言·c++·算法