首页 > 其他分享 >链表经典问题

链表经典问题

时间:2022-12-17 17:45:17浏览次数:36  
标签:问题 head cur self next 链表 经典 节点

链表经典问题

1.反转链表

问题:将链表反转,并返回新的头节点。

思路:设置两个指针,反别表示现节点和前节点,遍历链表,同时设置一个临时指针储存下一个节点。然后让现指针的next指向前指针。

def reverseList(self, head):
        cur = head
        pre = None
        while cur:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        return pre

最后前节点pre即为新的头节点。

2.移除链表元素

问题:移除给出链表中的元素等于val的节点,并返回。

(1)递归

思路:函数先判断除头节点外的节点,不断调用该函数,使得找到末节点。当链表为空时返回,对于每个函数中头节点进行判断,如果节点的值等于val则返回head.next,相当于将该节点删除,返回剩下的节点,如果不等则返回该节点,即没有删除。直到最后对真正的头节点进行判断,递归结束。

def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
    if not head:
        return 
    head.next = self.removeElements(head.next,val)
    return head.next if head.val == val else head
(2)迭代

思路:设置一个指针,使他的next指向头节点。遍历链表,不断对指针的下一个节点进行判断,如果节点值等于val,则使指针的next指向next.next,就实现的删除。由于可能会删除头节点,所以需要设置一个哑节点使他的next指向真正头节点

def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
    dummyhead = ListNode()
    dummyhead.next = head
    temp = dummyhead
    while temp.next:
        if temp.next.val == val:
            temp.next = temp.next.next
        else:
            temp = temp.next
    return dummyhead.next
(3)双指针

思路:设置两个指针分别表示前一个节点和现在的节点,遍历链表当节点的值等于val时,判断节点的位置,分别进行不同的删除操作。因为保存的前一个节点,所以删除操作会简单很多。

def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
    cur = head
    pre = None
    while cur:
        if cur.val == val:
            if cur == head:
                head = cur.next
                cur = head
            elif cur.next == None:
                pre.next = None
                break
            else:
                cur = cur.next
                pre.next = cur
        else:
            pre = cur
            cur = cur.next
    return head
3.奇偶链表

问题:给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。

思路:先分别建立两个新链表,设置两个指针,表示奇数项节点和偶数项节点,遍历链表。指针每次走两个节点,表示都为奇数项或都为偶数项。最后让偶数链表的头节点与奇数链表的末节点相连。

注意:要先设置变量保存偶数项链表的头节点,如果想用head.next的方法访问是不行的,因为head现在与偶数项的头节点无关,head.next指向原来的head.next.next。

def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
    if not head:
        return head
    evenhead = head.next
    odd = head
    even = head.next
    while odd.next and even.next:
        odd.next = odd.next.next
        even.next = even.next.next
        odd = odd.next
        even = even.next
    odd.next = evenhead
    return head
4.回文链表

问题:给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false

有以下三种方法

(1)列表

思路:建立一个列表来储存链表的值,再反转列表,如果反转后相等则为回文链表。

def isPalindrome(self, head: Optional[ListNode]) -> bool:
    l = []
    temp = head
    while temp:
        l.append(temp.val)
        temp = temp.next
    r = l.copy()
    r.reverse()
    return  r == l
(2)迭代

思路:先设置一个指针指向头节点位于递归函数外,再设置递归函数。递归不断找到与递归函数外指针对称的节点,判断是否相等,不相等返回Flase。同时如果相等,则递归函数外指针往前进一个节点,即指向它的next。简单来说就是先判断头节点和末节点是否相等,然后分别前进和后退一个节点再进行判断。

def isPalindrome(self, head: Optional[ListNode]) -> bool:
    self.head = head

    def check(cur = head):
        if cur:
            if not check(cur.next):   #这一行保证只要递归函数的一层不相等,就整个函数返回False
                return False
            if cur.val != self.head.val:
                return False
            self.head = self.head.next
        return True

    return check()
(3)快慢指针

思路:设置快慢指针,快指针一次走两个节点,慢指针一次走一个节点。当快指针走完整个链表时,慢指针刚好走到链表的中间节点。然后对慢指针之后的链表进行反转,再与反转前的链表进行对比,如果不等就返回False,否则返回True。

def isPalindrome(self, head: Optional[ListNode]) -> bool:
    self.fast = self.slow = temp = head
    while self.fast.next and self.fast.next.next:
        self.fast = self.fast.next.next
        self.slow = self.slow.next
    self.slow = self.reverse(self.slow)
    while self.slow and temp:
        if temp.val != self.slow.val:
            return False
        temp = temp.next
        self.slow = self.slow.next
    return True

def reverse(self,head):
    cur = head
    pre = None
    while cur:
        temp = cur.next
        cur.next = pre
        pre = cur
        cur = temp
    return pre

标签:问题,head,cur,self,next,链表,经典,节点
From: https://www.cnblogs.com/102204216zxf/p/16989254.html

相关文章

  • 树转二叉树结点个数问题
    已知一棵有2011个结点的树,其叶结点个数为116,该树对应的二又树中无右孩子的结点的个数是()......
  • 结构体&指针&链表
    一.结构体0.前言我们所学过的类型如:char,int,float,double等,都只能描述单一变量。但是结构体,顾名思义,是多个变量的集合,其中包含多个单一变量。所以C语言就发明了结构体用......
  • 打印tensorboard记录的数据(解决tf2下的问题)
    读取并导出Tensorboard中数据读取tensorboard日志数据代码fromtensorboard.backend.event_processingimportevent_accumulator#加载日志数据ea=event_accumulator......
  • git相关问题连接
    创建vue相关项目vuecreateh5创建gitee,SSH仓库方便vsc上直接提交​​https://blog.csdn.net/forever__fish/article/details/123555638​​生成key方法​​https://gitee.......
  • 搜索问题 DFS BFS
    搜索问题DFSBFSDFSdfs更多用于解决存在性问题和遍历性问题他可以很容易找到一个东西是否存在,比如说一条路径是否存在,不需要恢复现场也可以比较方便的展示所有的情况,......
  • 解决Mac ControlCe默认端口5000与项目冲突问题
    项目默认端口为5000mac控制中心也为5000kill杀死后还是自动重启占用5000只需要关闭隔空播放接收器即可......
  • java跨域问题解决
    问题描述:在使用前后端分离的情况下,前端访问后端时会出现跨域问题解决方式:1.设置跨域1)、单个控制器方法CORS注解在单个方法中加入注解@CrossOrigin。2)、整个控制器......
  • 2022.12.17 - vue Router4 关于嵌套路由配置无匹配页面导致失效问题
    constroutes=[ { path:'', name:'home', component:()=>import(/*webpackChunkName:"home"*/'../pages/index'), children:[ { path:'', ......
  • Linux系统Ubuntu中文输入法调用不成功或出现键盘输入键位不对问题
    出现这个问题主要还是因为使用系统自带输入法系统IBus问题,本人使用的版本为Ubuntu22.10,从搜狗输入法官网下载https://shurufa.sogou.com/linux,下载后可直接安装,如果不行......
  • 关于完全背包问题的内外层循环顺序问题
    完全背包由于物品可以重复放置,我觉得就应该物品在内层循环,这样在每一个背包容量都可以考虑到这个物品。在leetcode上有些题可以把物品在外层循环进行答题,也可以ac,但是从可......