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

了解链表

打字的时候不注意,发现写了节点和结点两个表述,将就看吧

什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。

链表的入口节点称为链表的头结点也就是head。

链表的定义

python 复制代码
# 定义链表的节点类
class ListNode:
    """
    链表节点类,每个节点包含:
    - val: 节点存储的值
    - next: 指向下一个节点的指针(默认None)
    """
    def __init__(self, val=0, next=None):
        self.val = val  # 节点值
        self.next = next  # 指向下一个节点的引用

链表的操作

删除节点

添加节点

与数组的区别

数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。

链表是通过指针域的指针链接在内存中各个节点。

性能对比

203.移除链表元素

题目链接203. 移除链表元素 - 力扣(LeetCode)

思路

删除这个节点,需要他的前一个指向他的后一个,但如果需要删除的节点是头节点,那他的前一个节点又是什么?可以用head=head->next,这样我们需要区分头节点和非头节点去进行删除操作。还有一个方法是设定虚拟头节点,这样不需要区分头结点和非头结点进行删除操作。

其实设定虚拟头结点的方法在很多链表类的题目里面都有用到

伪代码

python 复制代码
dummyhead=new()
dummyhead->next=head//把这个虚拟头结点放在head的前面
cur=dummyhead//临时指针遍历链表,删cur->next
while(cur->next!=null):
    if(cur->next==target):
        cur->next=cur->next->next
    else:
        cur=cur->next
return dummyhead->next//新链表的头结点

写题

报错1

修改:

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

错误2

修改:

是删除的结果有问题,看删除逻辑

发现我这一行写错了

python 复制代码
            if(cur.next.val==val):
                cur.next=cur.next.next

之前写的是cur.val==val

提交成功

python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        dummy=ListNode(0)
        dummy.next=head
        cur=dummy
        while(cur.next):
            if(cur.next.val==val):
                cur.next=cur.next.next
            else:
                cur=cur.next
        return dummy.next

707.设计链表

题目链接707. 设计链表 - 力扣(LeetCode)

看到这里一半的力气都没了,怎么要写这么多函数

思路

设定虚拟头结点

另外需要注意,第0个结点是头结点

伪代码

python 复制代码
cur=dummyhead->next
//获取第n个节点的值
while(n):
    cur=cur->next
    n--
return cur->val//如果n=0不进入whle循环,直接返回头结点的值,所以上面给cur赋值的时候也是给的头结点

//头部插入节点
newnode=Newnode()
newnode->next=head
dummyhead->next=newnode
//注意顺序如果先dummyhead->next=newnode,后面head就获取不到了,所以是先给head

//尾部插入节点
//找尾部
cur=dummyhead
newnode=Newnode()
while(cur.next):
    cur=cur.next
cur.next=newnode

//第n个节点前插入节点
//需要cur指向第n-1个节点,然后cur.next指向第n个节点
cur=dummyhead
newnode=Newnode()
while(n):
    cur=cur->nxt
    n--
newnode->next=cur.next
cur.next=newnode
 
//删除第n个节点
cur=dummyhead
//需要cur指向第n-1个节点,然后cur.next指向第n个节点
while(n):
    cur=cur->nxt
    n--
cur->next=cur->next->next

写题

python 复制代码
class ListNode:
    def __init__(self,val=0,next=None):
        self.val=val
        self.next=next

class MyLinkedList:
    def __init__(self):
        self.dummy=ListNode(0)
        self.size=0

这部分看了题解,因为自己写的时候大脑一片空白

后面对链表操作是自己写的

错误1

测试用例部分通过,提交的时候出了问题,我再看看。有一半通过一半没通过??

addAtIndex 方法的边界条件错误

  • 官方 / 常规逻辑中,addAtIndex(index, val) 允许 index == self.size(此时等价于在尾部添加),但写的条件是 index>=self.size 就返回 -1,直接限制了 "在尾部添加" 的合法场景。

  • 该方法的返回值错误:题目要求这些操作(add/delete)是None类型,你却返回了-1(只有get方法需要返回值)。

  1. deleteAtIndex 方法的返回值错误
  • 和上面同理,deleteAtIndex 不需要返回值,但写了 return -1,不符合规范。

提交成功

就是边界条件,特别是那个size,还有cur到哪个地方开始操作

python 复制代码
class ListNode:
    def __init__(self,val=0,next=None):
        self.val=val
        self.next=next

class MyLinkedList:
    def __init__(self):
        self.dummy=ListNode(0)
        self.size=0

    def get(self, index: int) -> int:     
        if index<0 or index>=self.size:
            return -1
        cur=self.dummy.next
        while(index):
            cur=cur.next
            index-=1
        return cur.val


    def addAtHead(self, val: int) -> None:
        newnode=ListNode(val)
        newnode.next=self.dummy.next
        self.dummy.next=newnode
        self.size+=1
        
    def addAtTail(self, val: int) -> None:
        cur=self.dummy
        newnode=ListNode(val)
        while(cur.next):
            cur=cur.next
        cur.next=newnode
        self.size+=1

    def addAtIndex(self, index: int, val: int) -> None:
        if index<0 or index>self.size:
            return 
        cur=self.dummy
        newnode=ListNode(val)
        while(index):
            cur=cur.next
            index-=1
        newnode.next=cur.next
        cur.next=newnode
        self.size+=1

    def deleteAtIndex(self, index: int) -> None:
        if index<0 or index>=self.size:
            return 
        cur=self.dummy
        while(index):
            cur=cur.next
            index-=1
        cur.next=cur.next.next
        self.size-=1
        


# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)

再练习练习

下午又写了一遍,最重要还是搞清楚从哪个地方找,是对cur做处理还是cur的next做处理

获取当前index的值,cur就要到index位置

在index位置添加,就在cur(index的前一个位置)和cur.next(index位置)之间加入

在index位置删除,就在cur(index的前一个位置),cur.next(index位置)

另外就是index是否可以包括self.size

206.反转链表

题目链接206. 反转链表 - 力扣(LeetCode)

思路

绕,转圈

伪代码

python 复制代码
cur=head
pre=null//cur的前一个节点
//什么时候遍历结束,cur一直往后面走,走,到最后一个元素还是需要反转,但是最后一个元素后面的null到这里就可以结束了
while(cur):
    temp=cur->next//需要一个临时指针把cur的下一个位置保存
    cur->next=pre
    pre=cur
    cur=temp
return pre

2,3是把pre和cur往后面移的意思

写题

中间有一次返回是空,return cur

应该是return pre

python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        pre=None
        cur=head
        while(cur):
            temp=cur.next
            cur.next=pre
            pre=cur
            cur=temp
        return pre
相关推荐
仰泳的熊猫1 小时前
题目2571:蓝桥杯2020年第十一届省赛真题-回文日期
数据结构·c++·算法·蓝桥杯
尽兴-1 小时前
Redis7 底层数据结构解析
数据结构·数据库·缓存·redis7
逆境不可逃2 小时前
LeetCode 热题 100 之 33. 搜索旋转排序数组 153. 寻找旋转排序数组中的最小值 4. 寻找两个正序数组的中位数
java·开发语言·数据结构·算法·leetcode·职场和发展
leaves falling3 小时前
二分查找:迭代与递归实现全解析
数据结构·算法·leetcode
杰克尼4 小时前
知识点总结--01
数据结构·算法
咱就是说不配啊5 小时前
3.20打卡day34
数据结构·c++·算法
cui_ruicheng5 小时前
C++数据结构进阶:哈希表实现
数据结构·c++·算法·哈希算法·散列表
光电笑映5 小时前
高阶数据结构之红黑树详解
数据结构
逆境不可逃6 小时前
LeetCode 热题 100 之 35. 搜索插入位置 74. 搜索二维矩阵 34. 在排序数组中查找元素的第一个和最后一个位置
数据结构·算法·leetcode