力扣刷题记录2

标明来源,题目及答题灵感均来自:https://leetcode.cn/problems/add-two-numbers/description/

这个题是有关链表的,我先记录一下知识点,不然我不会做。

一、什么是链表

链表的通俗理解:链表是一种非连续、非顺序的线性顺序结构,和我们熟悉的数组是亲兄弟,都是存一组有序的数据,但是存储方式完全不同。

数组:所有元素在内存中是连续挨在一起的,比如[1,2,3,4]内存地址是连续的;

链表:所有元素(节点)在内存中是分散存储的,每个节点之间靠指针相互连接,像一串珍珠项链,珍珠=节点,绳子=指针。

链表的最小单位:节点(Node),节点是链表的核心,链表的所有数据都储存在节点里。

python 复制代码
# 单向链表的节点定义
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val   # 存放的【数据/值】,比如数字 2、5、9
        self.next = next # 【指针】,存放下一个节点的地址,指向链表的下一个节点

节点的两个核心属性:

self.val是当前节点存的实际数据,可以是数字、字符等;

self.next是当前节点的后继指针,指向下一个节点的内存地址,通过它能找到下一个元素,如果next=None,那么这个节点就是最后一个节点。

二、链表的核心分类

1、单链表

每个节点只有一个指针next,只能从头节点向尾结点的方向遍历,是所有链表的基础。

2、虚拟头节点

为什么需要虚拟头节点,因为单链表的头节点是入口,如果直接操作头节点,会有两个致命问题:

(1)链表为空时,头节点不存在,操作会报错;(2)拼接新链表时,需要单独处理第一个节点,逻辑变复杂。

虚拟头节点的定义:创建一个空值的节点,让这个空节点的next指向链表的真实头节点,这个空节点就是虚拟头节点。

核心特点:(1)只是一个占位符,不储存有效数据;(2)保持位置不动;(3)用一个移动指针绑定虚拟头节点,专门负责往后拼接或遍历;(4)最终结果取虚拟头节点.next,就是正常的链表头节点。

python 复制代码
dummy = ListNode()  # 创建虚拟头节点,值默认0
curr = dummy        # 移动指针绑定虚拟头节点
# ...中间拼接节点的逻辑...
return dummy.next   # 返回真实头节点

(三)单链表的6个核心基本操作

1、遍历列表

从头节点开始,一直往后走,直到指针为None

python 复制代码
def traverse(head):
    curr = head  # 定义指针,从头节点开始
    while curr:  # 只要指针不为空,就继续遍历
        print(curr.val)  # 访问当前节点的值
        curr = curr.next # 指针后移,关键步骤!

2、获取链表的长度(借助计数器)

python 复制代码
def get_length(head):
    count = 0
    curr = head
    while curr:
        count +=1
        curr = curr.next
    return count

3、查找链表中是否存在某个值

python 复制代码
def find_target(head, target):
    curr = head
    while curr:
        if curr.val == target:
            return True
        curr = curr.next
    return False

4、在链表尾部新增节点(让最后一个节点的next指向新节点)

python 复制代码
def add_at_tail(head, val):
    new_node = ListNode(val)  # 创建新节点
    if not head:  # 边界:链表为空时,新节点就是头节点
        return new_node
    curr = head
    while curr.next:  # 遍历到最后一个节点(curr.next=None时停止)
        curr = curr.next
    curr.next = new_node  # 拼接新节点
    return head

5、删除链表中指定值的节点(就是直接跳过)

python 复制代码
def remove_node(head, val):
    dummy = ListNode()  # 用虚拟头节点,避免头节点是目标节点的边界问题
    dummy.next = head
    curr = dummy
    while curr.next:
        if curr.next.val == val:
            curr.next = curr.next.next  # 跳过目标节点,完成删除
            break
        curr = curr.next
    return dummy.next

6、反转链表

python 复制代码
def reverse_list(head):
    pre = None   # 前驱节点初始为空
    curr = head  # 当前节点从头节点开始
    while curr:
        temp = curr.next  # 临时保存下一个节点,防止丢失
        curr.next = pre   # 反转指针:当前节点指向前驱节点
        pre = curr        # 前驱节点后移
        curr = temp       # 当前节点后移
    return pre  # 最终pre就是反转后的头节点

好了,接下来做一个例题:

题目:给你两个非空的链表,表示两个非负的整数。它们每位数字都是逆序存储的,并且每位数字只能储存一位数字。请你将两个数相加,并以相同形式返回一个和的链表。你可以假设除了数字0之外,它们不会以0开头。

python 复制代码
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        # 当前指针,结果链表:创建空的虚拟头节点,双指针指向它
        result = curr = ListNode()
        # 进位项:加法满10进1,初始值0
        remainder = 0

        # 循环条件:只要l1没遍历完 或者 l2没遍历完,就继续相加
        while l1 or l2 :
            # 取l1当前值,空则补0
            x = l1.val if l1 else 0
            # 取l2当前值,空则补0
            y = l2.val if l2 else 0

            # 计算当前位总和 = l1值 + l2值 + 上一位的进位
            total = x + y + remainder

            # 当前位存入【余数】,满10只留个位
            curr.next = ListNode(total%10)
            # 更新进位:满10进1,不满则为0
            remainder = total//10

            # 防止空链表调用.next报错:非空才后移指针
            if l1 : l1 = l1.next
            if l2 : l2 = l2.next
            # 结果链表指针后移,准备存下一位计算结果
            curr = curr.next

        # 循环结束后如果还有进位,单独新增一个节点存进位1
        if remainder : curr.next = ListNode(remainder)
        # 返回真正的结果链表头节点
        return result.next

ok,解放,明天继续。

相关推荐
列星随旋2 小时前
线段树和树状数组的学习
学习·算法
圣保罗的大教堂2 小时前
leetcode 61. 旋转链表 中等
leetcode
我爱cope3 小时前
【Agent智能体4 | 智能体AI的应用】
数据库·人工智能·职场和发展
全糖可乐气泡水3 小时前
Codex适配国产信创环境安装部署与技术适配全解析
开发语言·git·python·算法·百度
h_a_o777oah4 小时前
状态机+划分型 DP :深度解析K-划分问题下 DP 状态的转移逻辑(洛谷P2679 P2331 附C++代码)
c++·算法·动态规划·acm·状态机dp·划分型dp·滚动数组优化
05候补工程师4 小时前
从算法理想向工程现实的跨越:SLAM 核心架构、思维误区与 Nav2 实战避坑指南
人工智能·算法·安全·架构·机器人
手写码匠5 小时前
Android 17 适配实战指南:新特性解读、隐私变更与迁移全攻略
人工智能·深度学习·算法·aigc
珊瑚里的鱼5 小时前
leetcode42雨水
算法·leetcode
水木流年追梦6 小时前
大模型入门-大模型的推理策略
开发语言·python·算法·正则表达式·prompt
生成论实验室6 小时前
用事件关系网络重新理解AI(三):激活函数、微调与元学习
人工智能·学习·算法·语言模型·可信计算技术