测开准备-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

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

相关推荐
智者知已应修善业9 分钟前
【51单片机从奇数始再转偶数逐一点亮并循环】2023-9-8
c++·经验分享·笔记·算法·51单片机
倔强的猴子(翻版)15 分钟前
我用 Python 写了个排序库,一亿数据量下比 C 级 np.sort() 快 7 倍
人工智能·python·算法·阿里云·文心一言
郝学胜-神的一滴16 分钟前
深入理解回归损失函数:MSE、L1 与 Smooth L1 的设计哲学
人工智能·python·程序人生·算法·机器学习·数据挖掘·回归
努力努力再努力wz17 分钟前
【MySQL进阶系列】拒绝冗余SQL:带你透彻理解视图的底层逻辑
android·c语言·数据结构·数据库·c++·sql·mysql
iCxhust30 分钟前
在 emu8086 中可以直接编译运行的完整汇编程序,演示数组的定义、遍历、求和、求最大值。
开发语言·前端·javascript·汇编·单片机·嵌入式硬件·算法
Jinkxs38 分钟前
LoadBalancer- 常见负载均衡算法:轮询 / 加权轮询 / 最少连接等基础实现
运维·算法·负载均衡
Brilliantwxx1 小时前
【C++】认识vector(概念+题目OJ)
开发语言·c++·笔记·算法
m0_629494731 小时前
LeetCode 热题 100-----18.矩阵置零
数据结构·leetcode·矩阵
生成论实验室1 小时前
《事件关系阴阳博弈动力学:识势应势之道》第十篇:识势应势——从认知到行动的完整闭环
人工智能·算法·架构·创业创新·安全架构
risc1234561 小时前
SegmentTermsEnum#postings 和 IntersectTermsEnum#postings
算法·lucene