首页 > 其他分享 >代码随想录二刷(链表章节)

代码随想录二刷(链表章节)

时间:2024-07-30 19:28:16浏览次数:10  
标签:index cur val dummy self 随想录 next 链表 二刷

代码随想录二刷(链表章节)

在这里插入图片描述
链表就是通过指针串联在一起的线性结构,每个节点都是由一个数据域和指针域(存放下一个节点的指针)。
双链表就是每个节点中既有指向前一个节点的,也有指向后一个节点的。
在这里插入图片描述
循环链表就是把头和尾连起来。
在这里插入图片描述
性能分析如下:
在这里插入图片描述
下面来看下链表的具体题目:

Leetcode203

在这里插入图片描述
这里首先要明白处理链表一个技巧就是可以创立一个哨兵节点。这样就能避免处理一些特殊情况,比如只有头的情况下。这样的话,链表始终是有一个元素的。具体来说过程如下图

在这里插入图片描述

# @lc code=start
# 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(next = head)
        cur = dummy
        while cur.next:
            if cur.next.val == val:
                cur.next = cur.next.next
            else:
                cur = cur.next
        return dummy.next  

Leetcode707

在这里插入图片描述

具体程序如下:

class Listnode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class MyLinkedList:

    def __init__(self):
        self.dummy = Listnode()
        self.size = 0
    def get(self, index: int) -> int:
        if index < 0 or index >= self.size:
            return -1
        cur = self.dummy
        while cur.next:
            if index == 0:
                return cur.next.val
            cur = cur.next
            index -= 1
    def addAtHead(self, val: int) -> None:
        cur = self.dummy
        cur.next = Listnode(val,cur.next)
        self.size += 1
    def addAtTail(self, val: int) -> None:
        cur = self.dummy
        while cur.next:
            cur = cur.next
        cur.next = Listnode(val)
        self.size += 1
    def addAtIndex(self, index: int, val: int) -> None:
        cur = self.dummy
        if index > self.size or index < 0:
            return 
        for _ in range(index):
            cur = cur.next
        cur.next = Listnode(val, cur.next)
        self.size += 1
    def deleteAtIndex(self, index: int) -> None:
        cur = self.dummy
        if index >= self.size or  index < 0:
            return
        for _ in range(index):
            cur = cur.next
        cur.next = cur.next.next
        self.size -= 1

首先分析get函数的实现:
在这里插入图片描述
由于题目要求下标是从0开始,所以要用个self.size记录下链表中元素的数量。那么插入头部和插入尾部以及删除指定Index,都会涉及到self.size的变化。
首先要把下标无效的情况给排除掉。也就是

if index < 0 or index >= self.size:
            return -1

接下里操作链表的话都是要用哨兵节点(这样就可以将只有一个元素的特殊情况也给合并了)。用for循环遍历就可以:

        cur = self.dummy
        for _ in range(index):
            cur = cur.next
        return cur.next.val


插入到第一个元素之前,也就是插入到头之前。这时候就体会到哨兵节点的好用了。

cur.next = Listnode(val,cur.next)

cur代表哨兵节点,哨兵节点的下一个也就是头部的位置,所以创建一个值为val,并且这个节点为原来节点的下一个节点。这样就完成插入的操作了
删除操作的话 ,
在这里插入图片描述

所以还要先判断下标是否超范围:

        if index >= self.size or  index < 0:
            return

然后接着for循环去根据index来。然后要删除的节点。

        for _ in range(index):
            cur = cur.next

所以删除:cur.next = cur.next.next
如果不明白的话。画个图就好理解下,做关于链表的题目。
在这里插入图片描述

在这里插入图片描述
插入操作的也可以画个图:
在这里插入图片描述

        cur = self.dummy
        if index > self.size or index < 0:
            return 
        for _ in range(index):
            cur = cur.next
        cur.next = Listnode(val, cur.next)

下面来看下反转链表的题目。
在这里插入图片描述
这里采用双指针的思想,pre为该节点要指向的新位置,cur为当前要处理的节点。并且当前要处理的节点的下个位置的信息由于你改变了指向会丢失,所以要用临时变量temp给保存起来。这些操作完成后,pre移动到cur,然后cur移动到下个位置也就是pre的位置。
所以程序思路其实知道了双指针后,并不是很难写出来:

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        cur = head
        pre = None
        while cur:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        return pre

Leetcode24

下面来看下下道题两两交换的链表题目:

在这里插入图片描述
这个交换链表的也建议是画图的话更好去理解。
在这里插入图片描述
看着这个图去写程序就可以。

class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        dummy_head = ListNode(next = head)
        cur = dummy_head
        pre = None
        while cur.next and cur.next.next:
            temp1 = cur.next
            temp2 = cur.next.next.next
            cur.next = cur.next.next
            cur.next.next = temp1
            cur.next.next.next = temp2
            cur = cur.next.next
        return dummy_head.next

但是while循环要注意不止要判断Cur.next,还要判断cur.next.next。因为程序里面都是两两交换的。

Leetcode19

继续一道倒着删除链表的题目:
在这里插入图片描述

这道题思路是用双指针的思路,因为要删除倒数第n个节点。而链表的话只能按顺序遍历,所以用一个快指针,一个慢指针。快指针先走n步,然后在快指针的基础上慢指针移动,终止条件是快指针到达末尾。这样慢指针停的位置就是刚好要删除节点的前面一个。
具体原理如下:
在这里插入图片描述

class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        dummy_head = ListNode(0,head)
        slow,fast = dummy_head,dummy_head
        for _ in range(n+1):
            fast = fast.next
        while fast:
            slow = slow.next
            fast = fast.next
        slow.next=slow.next.next
        return dummy_head.next  

标签:index,cur,val,dummy,self,随想录,next,链表,二刷
From: https://www.cnblogs.com/bathwind/p/18333216

相关文章

  • 代码随想录day14 || 226 翻转二叉树,101 对称二叉树, 104 二叉树的最大深度, 111 二叉树
    226翻转二叉树funcinvertTree(root*TreeNode)*TreeNode{ //思考,广度优先遍历,对于每一层,翻转其左右子节点 ifroot==nil{ returnnil } queue:=list.New() queue.PushBack(root) size:=1//存储每一层的节点个数 forqueue.Len()>0{ varcountint ......
  • 代码随想录算法训练营第28天 | 贪心进阶
    2024年7月30日题122.买卖股票的最佳时机II上涨就买,下跌就不买。classSolution{publicintmaxProfit(int[]prices){intsum=0;for(inti=1;i<prices.length;i++){sum+=prices[i]-prices[i-1]>0?prices[i]-prices[i-1]:0;......
  • 代码随想录算法训练营第27天 | 初入贪心
    2024年7月29日题455.分发饼干先排序,然后依次分发即可。classSolution{publicintfindContentChildren(int[]g,int[]s){//对于每个孩子胃口,从小到大分配,且给尽可能少的饼干Arrays.sort(g);Arrays.sort(s);intcnt=0;......
  • 代码随想录——完全平方数(Leetcode 279)
    题目链接动态规划动态规划思路:状态定义:定义一个一维数组dp,其中dp[i]表示组成整数i所需的最少完全平方数的数量。状态初始化:将dp数组中的所有元素初始化为Integer.MAX_VALUE,表示初始状态下组成每个整数的完全平方数数量是无限大(即不可能)。但dp[0]需要初始化为0,因为组成......
  • 代码随想录 day39 零钱兑换 | 完全平方数 | 单词拆分
    零钱兑换零钱兑换解题思路还是完全背包的套路,但这次我们要求的是最小值,因此每次遍历的时候我们要找到最小值,每次给dp增加的大小不在是物品的价值而是长度,所以+1。知识点完全背包心得难点在于怎么样找到最小值完全平方数[完全平方数(https://programmercarl.com/0279.完......
  • 「代码随想录算法训练营」第二十三天 | 贪心算法 part1
    455.分发饼干题目链接:https://leetcode.cn/problems/assign-cookies/题目难度:简单文章讲解:https://programmercarl.com/0455.分发饼干.html视频讲解:https://www.bilibili.com/video/BV1MM411b7cq题目状态:初次有贪心算法的总体概念,有点懵思路:先将饼干尺寸大的满足胃口大......
  • 代码随想录day13 || 树定义以及遍历
    二叉树定义和种类二叉树是一种树形数据结构,其中每个节点最多有两个子节点,通常称为“左子节点”和“右子节点”。二叉树在计算机科学中有广泛的应用,比如表达式解析、排序算法、搜索算法等。二叉树的定义一个二叉树由一组节点组成,其中每个节点至多有两个子节点,分别称为左子节点和......
  • 最细哈希表相关的力扣题和讲解和Java、C++常用的数据结构(哈希法)来源于代码随想录,十分
    20240725一、什么时候适用什么样的结构。1.java中1.1HashSet:1.2TreeSet:1.3LinkedHashSet:1.4HashMap:1.5TreeMap:1.6LinkedHashMap:1.7总结2.c++中2.1std::unordered_set:2.2std::set:2.3std::multiset:2.4std::unordered_map:2.5std::map:2.6std::multimap:3代码......
  • 判断链表是否有环
    题目要求给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表无环,则返回null。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos来表示链表尾连接到链表中的位置(索引从0开始)。如......
  • 【代码随想录训练营第42期 Day10打卡 LeetCode 232.用栈实现队列 225. 用队列实现栈 2
    目录一、做题心得二、题目与题解题目一:232.用栈实现队列题目链接题解题目二:225.用队列实现栈题目链接题解题目三:20.有效的括号题目链接题解题目四:1047.删除字符串中的所有相邻重复项 题目链接题解三、小结一、做题心得今天是代码随想录训练营打卡的第1......