IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 算法题day2 -> 正文阅读

[数据结构与算法]算法题day2

作者:recommend-item-box-tow

2、链表

今天主要学习链表,在Python中并没有链表的数据结构,需要自己写,看LeetCode其内部似乎已经定义好了,我只需要使用。目前目标是尝试自己解,解不出来时学习别人解法,理解后,自己实现一遍,对比总结。

  • 对链表的常用技巧,添加哑节点,它的next节点指向链表的头节点。因为单链表的头节点没有上一个节点,在判断时经常需要额外判断,因此使用哑节点可以只考虑通用情况。
  • while head:可以对链表进行遍历

2.删除链表中倒数第N个节点

自己吭哧半天还是没懂链表如何求长度,它的迭代和数组也不一样。需要了解链表内部是如何实现的,我看一些文章中定义的类,感觉自己还是没明白,所以还是先看题目,从解题中去摸索。

看官方解析说此题有三种方法:

1.暴力解法:计算链表的长度L【需要遍历一遍链表】;找到倒数第N个节点的前一个节点(L-N),将其指针指向下下个节点。

# 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: ListNode, n: int) -> ListNode:
        #定义一个计算链表长度的函数
        def getLength(node: ListNode) -> ListNode:
            length = 0
            while node:
                length += 1
                node = node.next
            return length
        dummy = ListNode(0, head)  #在链表头部创建哑变量
        length = getLength(dummy)
        cur = dummy  #将链表浅层复制给cur,不复制最后只会返回删除后的变量
        for i in range(1, length-n):
            cur = cur.next   #找到删除的前一个变量
        cur.next = cur.next.next  #将此变量的指针指向下下个变量
        return dummy.next   #返回dummy.next,因为dummy包括哑变量,所以要.next

2.栈:因为需要倒数,所以可使用栈。栈是先进后出,在遍历节点的时候将节点存入栈中,然后弹出第n个,弹出后的栈顶就是需要的节点,将此节点指向下下个节点。官方文档中的栈?,栈可以使用list实现,.append(n)可以添加元素,.pop()可以弹出元素。

def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(0, head)  #增加哑变量
        stack = []   #创建栈
        cur = dummy
        while cur:
            stack.append(cur)   #将链表的元素添加进栈
            cur = cur.next
        for i in range(n): 
            stack.pop()  #将n个元素弹出,range是从0~n-1,刚好个数一致。
        prev = stack[-1]  #取栈顶元素
        prev.next = prev.next.next  #更改链接
        return dummy.next

3.双指针:在解特定位置搜索的题可以采用双指针,fast指针和slow指针,fast指针先移动n,然后fast与slow一起移动,当fast指向最后一个指针时,slow指针指向的就是待删除的元素;因为需要删除的前一个元素,因此slow指针从哑变量开始更合适。

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(0, head)
        fast = head
        slow = dummy  #从0开始
        for i in range(n):
            fast = fast.next  #先走n个
        while fast:
            fast = fast.next
            slow = slow.next   #fast遍历完成所对应的slow
        slow.next = slow.next.next
        return dummy.next

3.反转链表

看到反转链表第一印象是使用栈,但是其输出也要求是链表,那么在出栈的时候把其变成链表。链表重要的是它的一个指向。

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        stack = [None]  #不写None会超时
        while head:
            stack.append(head)
            head = head.next
        head = stack.pop()
        cur = head         #得到头结点
        while stack:
            cur.next = stack.pop()   #将之后pop的值给next
            cur = cur.next  #cur更新
        return head

作者:qingyangwu14
链接:https://leetcode-cn.com/problems/reverse-linked-list/solution/fan-zhuan-lian-biao-zhan-shi-xian-by-qingyangwu14/
来源:力扣(LeetCode)

1.将指针反转,属于双指针迭代。直接思想是定义两个指针pre和cur,把cur.next = pre,然后cur指针向前移动,遍历完即可。但是如果直接设置,那么cur.next因为已经更改就无法转移到下一个,因此需要一个中间变量temp存储之前索引temp = cur.next,然后再执行cur.next = pre,然后进行移动,把当前的cur给pre:pre=cur,cur往下移动cur = temp。【这个逻辑自己想不清,需多练,看的播放最多的那个讲解视频】

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        pre = None
        cur = head
        while cur != None:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
#因为表头在末尾,所以返回pre
        return pre

2.使用递归实现,递归要求有三个规则:

可以分解成子问题;子问题的求解方式与大问题一致;存在最小子问题。

因为此问题可以分解成头结点与子链表,并把指向进行反转。【从顶端来思考似乎能想明白。。。】

def reverseList(self, head: ListNode) -> ListNode:
    if head is None or head.next is None:
        return head   #终止条件
    
    p = self.reverseList(head.next)   #递,拆分
    head.next.next = head    #归,反转
    head.next = None

    return p

作者:tangweiqun
链接:https://leetcode-cn.com/problems/reverse-linked-list/solution/shi-pin-jiang-jie-die-dai-he-di-gui-hen-hswxy/
来源:力扣(LeetCode)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-22 14:55:44  更:2021-09-22 14:57:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 13:19:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码