首页 > 其他分享 >234. 回文链表

234. 回文链表

时间:2023-12-10 20:34:59浏览次数:27  
标签:head return 复杂度 链表 堆栈 234 回文

题目介绍

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

示例 1:

输入:head = [1,2,2,1]
输出:true

示例 2:

输入:head = [1,2]
输出:false

提示:

  • 链表中节点数目在范围\([1, 10^{5}]\) 内
  • \(0 <= Node.val <= 9\)

进阶:你能否用 \(O(n)\) 时间复杂度和 \(O(1)\) 空间复杂度解决此题?

题解

2.1 双指针(链表转换数组)

代码

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int> arr;
        int i = 0, j =0;
        while (head){
            arr.push_back(head->val);
            head = head ->next;
        }
        j = arr.size() - 1;
        while (i < j){
            if (arr[i++] != arr[j--]) return false;
        }
        return true;
    }
};

复杂度分析

时间复杂度:O(n),其中 nnn 指的是链表的元素个数。
第一步: 遍历链表并将值复制到数组中,O(n)。
第二步:双指针判断是否为回文,执行了 O(n/2) 次的判断,即 O(n)。
总的时间复杂度:O(2n)=O(n)O(2n) =O(n)。
空间复杂度:O(n),其中 n 指的是链表的元素个数,我们使用了一个数组列表存放链表的元素值。

2.2 递归

思路

回文链表最重要的是能同时拥有指向头尾的指针,方便进行比较。
我们联想到使用递归可以进入到最深层也就是尾结点,递归的回调也弥补了单向链表无法向前回溯的缺陷。然后在设置一个全局指向首节点的指针,使用双指针思路即可。

代码

class Solution {
    ListNode *frontPointer;
public:
    bool recursicvelyCheck(ListNode *currentNode){
	if (currentNode != nullptr){ //回调返回条件:遍历到尾结点
		if(!recursicvelyCheck(currentNode->next)) return false; //这里实现递归。如果出现一个不成立的情况,后续回调均返回false;
		if(currentNode -> val != frontPointer -> val) return false; // 非回文链表情况。
		frontPointer = frontPointer -> next; // 双指针的同步.
	}
	return true; //作为最深层的返回值
   }
    bool isPalindrome(ListNode* head) {
        frontPointer = head;
        return recursicvelyCheck(head);
    }
};

复杂度分析

时间复杂度:O(n),其中 n 指的是链表的大小。
空间复杂度:O(n),其中 n 指的是链表的大小。我们要理解计算机如何运行递归函数,在一个函数中调用一个函数时,计算机需要在进入被调用函数之前跟踪它在当前函数中的位置(以及任何局部变量的值),通过运行时存放在堆栈中来实现(堆栈帧)。在堆栈中存放好了数据后就可以进入被调用的函数。在完成被调用函数之后,他会弹出堆栈顶部元素,以恢复在进行函数调用之前所在的函数。在进行回文检查之前,递归函数将在堆栈中创建 nnn 个堆栈帧,计算机会逐个弹出进行处理。所以在使用递归时空间复杂度要考虑堆栈的使用情况。
这种方法不仅使用了 O(n) 的空间,且比第一种方法更差,因为在许多语言中,堆栈帧的开销很大(如 Python),并且最大的运行时堆栈深度为 1000(可以增加,但是有可能导致底层解释程序内存出错)。为每个节点创建堆栈帧极大的限制了算法能够处理的最大链表大小。

2.3

思路

代码

标签:head,return,复杂度,链表,堆栈,234,回文
From: https://www.cnblogs.com/trmbh12/p/17893178.html

相关文章

  • 代码 测试用例 测试结果 测试结果 24. 两两交换链表中的节点
    给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例1:输入:head=[1,2,3,4]输出:[2,1,4,3]示例2:输入:head=[]输出:[]示例3:输入:head=[1]输出:[1] 提示:链表中节点的数目在范围 [0,100] 内......
  • 160.相交链表
    1.题目介绍给你两个单链表的头节点 \(headA\)和\(headB\),请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回\(null\)。图示两个链表在节点\(c1\)开始相交:题目数据保证整个链式结构中不存在环。注意,函数返回结果后,链表必须保持其原始结构......
  • 【JavaSE】数据结构(栈、队列、数组、链表)
    什么是数据结构?数据结构是计算机底层存储、组织数据的方式,是指数据相互之间是什么方式排列在一起的常见的数据结构栈、队列、数组、链表二叉树、二叉查找树、平衡二叉树、红黑树哈希表栈特点:先进后出队列特点:先进先出数组特点:有索引,内存连续优点:查询速度快O(1)缺点:增......
  • 【LeetCode-中等-链表】两数相加
    这是个关于链表的题目,以前在C#中写代码时,对链表接触比较少,所以刚好接这个题目来更好的熟悉一下链表题目大概是这样的,给你两个非空的链表,表示两个非负的整数.它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字 =》首先我们来理解这句话是什么意思我们来看......
  • [LeetCode Hot 100] LeetCode23. 合并K个升序链表
    题目描述思路:优先队列使用优先队列这个数据结构,对于这个数据结构,我们不用去管内部是如何实现的,我们只要知道有这么一种数据结构能帮助我们将一堆数据塞到优先队列这一个黑盒中,然后我们可以获取这堆数中最小的值或者最大的值。代码一:/***Definitionforsingly-linkedlis......
  • LeetCode876. 链表的中间结点
    题目描述思路:快慢指针快指针一次走两步慢指针一次走一步当快指针到达末尾的时候,慢指针所指的就是链表的中点方法一:/***Definitionforsingly-linkedlist.*publicclassListNode{*intval;*ListNodenext;*ListNode(){}*ListNode(......
  • 数据结构:单链表——定义、插入、删除
    1、查找元素查找第i个元素LNode*GetEleme_i(LinkListL,inti){if(i<1){returnNULL;}LNode*p;p=L;intj=0;while(p!=NULL&&j<i){p=p->next;j++;}returnp;}查找e元素的结点LNode*GetEleme_e(LinkList&L,ElementTypee){LNode*p;p=L;while......
  • C 语言实现抽象数据类型(ADT)之链表
    C语言实现抽象数据类型(ADT)之链表1什么是链表?(懂跳)C语言本身自带了很多基本数据类型,每种基本数据类型的变量总是代表着某个数据,比如:我们通常用整型变量来计数,用浮点型变量来保存价格这样的数据……intcount;doubleprice;而有时候我们需要表示的数据很复杂,比如我们想要......
  • H7-TOOL发布2.24固件,增加CMSIS-SVD解析,RTOS Trace链表,I2C/SPI从机,CANopen解析等,脱机烧
    H7-TOOL详细介绍(含操作手册):http://www.armbbs.cn/forum.php?mod=viewthread&tid=89934视频介绍:https://www.bilibili.com/video/BV1494y1j7mj【PC软件】V2.2.41.脱机烧录功能升级  -新增GD32C10x系列  -新增钜泉光电HT502x  -新增英飞凌TLE987x系列  -新......
  • 1234435
    我觉得这道题目如果只有第一个问题的话,排序方式是多种多样的,而且考虑的对象也可以是机器比如我可以给机器按照\(y\)从小到大排序,然后依次考虑每个机器,对于每个机器,在能选择的任务中选择\(x\)最大的即可但这个时候就没有办法保证价值最大了,所以这道题启发我们,如果一道题目有多维......