启发我们从后向前遍历链表的方式--力扣简单题,虽然不是最优解,但是很巧妙的一个解法

题目描述

在这里插入图片描述

思路

看到这个题,当然最简单的方法就是变成字符串,然后用字符串判断
不过,这样太Low了,想想别的办法

借鉴一下字符串的回文判断,是从两头向中间逐个遍历对比
但是链表它本身是单向的,没有向前的指针,只有向后的。也就是说,从前往后遍历是很简单的,但是从后往前可就不太容易了,所以借助链表本身肯定不行,还得借助别的方法,能够从后向前的。

这里想到栈,因为对于链表而言,从前向后,我们可以进栈,从后向前,正好我们可以利用出栈来实现从后向前的遍历

别急,你要是看到这里就去写下了这样一行:

class Stack:

好了,你又Low了,这样自定义一个数据结构,来实现回文链表的判定,那跟我用数组有什么区别呢。同样都是借助了别的数据结构来实现,至少得定义这样的数据结构

那栈还能怎么用?

没错就是递归,写一个递归函数,从而让他的栈存在于调用过程中,岂不妙哉

代码实现

这次代码讲解部分我采用当时编写时的思路,一点一点把代码放上来
这次测试用的是数组 [1, 2, 3, 4, 6, 4, 3, 2, 1]
直接用力扣官方的代码

首先,我们既然需要前后对比,在递归调用时,必须要直接让一个指针到达链表尾部,同时内存栈中已经存放下了前面所有的调用

	def recursively_check(current_node=head):
        if current_node is not None:
            if not recursively_check(current_node.next):

到这里,内存栈就已经放下了之前所有的调用,每一次调用对应一个节点,直到current node为空为止
在这里插入图片描述
好了,这一层调用该结束了,那这里应该返回True才行,False的话,就需要一路返回False回主进程了。

	def recursively_check(current_node=head):
        if current_node is not None:
            if not recursively_check(current_node.next):
            	return False
        return True

在这里插入图片描述
返回True之后,进行判断该层的current_node的value是否和前面对应的front_node的value相等,那么也就是说,在每一次调用该函数的时候,前面也需要一个指针并不停向后移动

所以,这里加上判断语句

	def recursively_check(current_node=head):
        if current_node is not None:
            if not recursively_check(current_node.next):
            	return False
            if self.front_pointer.val != current_node.val:
                return False
            return True
            

再加上一个front_node,作为从前向后的指针

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:

        self.front_pointer = head

        def recursively_check(current_node=head):
            if current_node is not None:
                if not recursively_check(current_node.next):
                    return False
                if self.front_pointer.val != current_node.val:
                    return False
                self.front_pointer = self.front_pointer.next
            return True

        return recursively_check()

然后这个代码就编写完成了,成功使用了递归调用,实现了链表从后向前的访问

感兴趣的大家可以把这段完整的代码复制到自己本地的编译器中,然后debug看一下执行的流程

自己造了两个轮子:ListNode和list_to_listNode

class ListNode:
    __slots__ = ('val', 'next')

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


def list_to_listNode(list) -> ListNode:
    dummy = ListNode()
    ptr = dummy
    for element in list:
        ptr.next = ListNode(element)
        ptr = ptr.next
    return dummy.next


class Solution:
    def isPalindrome(self, head: ListNode) -> bool:

        self.front_pointer = head

        def recursively_check(current_node=head):
            if current_node is not None:
                if not recursively_check(current_node.next):
                    return False
                if self.front_pointer.val != current_node.val:
                    return False
                self.front_pointer = self.front_pointer.next
            return True

        return recursively_check()


if __name__ == '__main__':
    print(Solution().isPalindrome(list_to_listNode([1, 2, 3, 4, 6, 4, 3, 2, 1])))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值