算法题解记录19+++回文链表(百日筑基)

题目描述:

        难度:简单

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

示例 1:

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

示例 2:

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

约束:

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

解题准备:

        1.回文的概念:回文是指,倒着读和正着读一致的数、字符串或链表,比如:121,"sks","oopoo"

        2.链表:链表是一种线性结构,和数组类似。二者的本质区别,是链表不拘束于存储区块,其允许“任意存储”。比如:节点a存在地址1,而a的下一个节点b,存储在地址100。

        3.了解本题可能存在的基础操作:判断一个链表是否回文,必然要遍历一遍链表,所以涉及到链表的查找;;其余的目前看不出。

        4.链表的查找:由于链表的存储地址不确定,所以寻找某一个节点,只能从头节点head开始查找,对于随机出现的数,查找的时间复杂度为O(n)。

解题思路:

        由于链表是一个线性结构,其本质类似数组,不妨从数组的角度出发,思考:判断一个数组是否回文,该如何判断?

        很容易想到使用“双指针”【假设数组非null】:

        1.i指向下标0的元素,j指向下标len-1的元素。

        2.判断i、j的元素是否相等,如果不相等,返回false,否则i++、j--,如此迭代。

        3.边界考虑:如果len是偶数,会有什么情况?如果len是奇数呢?

        4.对len为偶数:此时,i、j最后一次判断,理应在i=len/2-1,j=len/2的位置。接着,i++、j--,此时i=len/2,j=len/2-1》》i>j,结束循环。

        5.对len为奇数:对此,i、j最后一次判断,是i=len/2-1,j=len/2+1。接着,i++,j--,导致i==j,于是结束循环。

        6.总结:如果i>=j,就可以结束循环,并且返回true。

        不过,由于链表不支持“随机访问”,对于某个节点node,node无法知道其上一个节点是什么,因此,数组的思路行不通。【或者可以理解为:链表没有下标关系】

        不过,链表和数组都是线性结构,很容易相互转换。

        思路1:链表转为数组

                如题,遍历一次链表,把每个节点的值存入数组,最后在数组中判断。

                这个思路问题在于:我们最初,不知道链表的长度。

                不过,既然我们只是想拿到,链表所对应数组的下标关系,完全可以采用ArrayList类辅助。

                因此,这个思路包括两步:第一步,遍历一次链表,转化为数组ArrayList;;第二步,遍历一次【只用遍历一半的元素】ArrayList,查看是否回文。

                总的迭代次数为O(n+n/2),总时间复杂度为O(n)

        思路2:用栈来辅助

                其实这个思路不如思路1简单方便,而且时间复杂度也相当,只是提供了一种新思路吧。

                第一步,遍历一次链表,拿到链表的长度len。

                第二步,将ptr指向head,再次遍历。【如果len是奇数,只用遍历len/2-1次,len是偶数,则遍历len/2次】

                遍历的同时,把数组存储进栈中。(栈可以用单调栈Deque,节省了并发处理等处理,速度非常快)

                第三步,如果len是奇数,把ptr指向ptr的下一个节点。

                第四步,继续遍历ptr,并与栈pop出的元素比较。如果不同,返回false。

                结束条件:栈为null,或者ptr为null;再或者,用for循环,遍历len/2次。

解题难点分析:

代码:

        思路1,链表转为数组:

class Solution {
    public boolean isPalindrome(ListNode head) {
        // 实例化链表对象
        List<Integer> temp = new ArrayList<Integer>();

        // 对于null的处理
        if(head==null || head.next==null){
            return true;
        }

        ListNode ptr=head;

        // 遍历一遍,并且记录所有节点值
        while(ptr!=null){
            temp.add(ptr.val);
            ptr=ptr.next;
        }

        // 记得指回头节点
        ptr=head;

        // 遍历一半节点
        for(int i=temp.size()-1; i>=temp.size()/2; i--){
            if(temp.get(i)!=ptr.val){
                return false;
            }
            ptr=ptr.next;
        }

        return true;
    }
}

        思路2,用栈辅助:

class Solution {
    public boolean isPalindrome(ListNode head) {
        // 单调栈,速度更快
        Deque<ListNode> tem=new LinkedList<>();
        int i=0; // 链表长度
        ListNode ptr=head;

        // 对null的特殊处理
        if(head==null || head.next==null){
            return true;
        }

        // 得到链表长度
        while(ptr!=null){
            i++;
            ptr=ptr.next;
        }

        // 指回头节点
        ptr=head;

        // 遍历一半,拿到前半部分节点
        for(int j=0; j<i/2; j++){
            tem.push(ptr);
            ptr=ptr.next;
        }

        // 奇数ptr指向ptr的next
        if(i%2==1){
            ptr=ptr.next;
        }

        // 判断回文否
        for(int j=0; j<i/2; j++){
            if(tem.pop().val!=ptr.val){
                return false;
            }
            ptr=ptr.next;
        }
        

        return true;
    }
}

以上内容即我想分享的关于力扣热题19的一些知识。

        我是蚊子码农,如有补充,欢迎在评论区留言。个人也是初学者,知识体系可能没有那么完善,希望各位多多指正,谢谢大家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/561701.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin语法快速入门--变量声明(1)

Kotlin语法入门–变量声明&#xff08;1&#xff09; 文章目录 Kotlin语法入门--变量声明&#xff08;1&#xff09;一、变量声明1、整型2、字符型3、集合3.1、创建array数组3.2、创建list集合3.3、不可变类型数组3.4、Set集合--不重复添加元素3.5、键值对集合Map 4、kotlin特有…

【Python系列】python 如何打印带时间的日志

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【软件测试】正交表测试例题

【软件测试】正交表测试 例题1答案 例题2答案 例题3答案 例题1 很多Word编辑器都有字体修饰功能&#xff0c;可以将一个字加粗、倾斜、以及加上下划线。一个字可以同时被加粗和倾斜&#xff0c;也可以同时被倾斜和加下划线。三种因子Bold, Italic, Underline的效果可以任意组合…

累加(C语言)

一、题目&#xff1b; 二、N-S流程图&#xff1b; 三、运行结果&#xff1b; 四、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int i 0;int j 0;int n 5;int result 0;int sum 0;//运算&#…

【氧化镓】Ga2O3 MOSFET器件的单SEB机制TCAD研究

本文是一篇关于氧化镓(Ga2O3)金属氧化物半导体场效应晶体管(MOSFET)在单粒子烧毁(single event burnout, SEB)事件中的机制研究的文章。文章通过使用技术计算机辅助设计(TCAD)模拟来探究侧向耗尽型氧化镓MOSFET设备在SEB中的敏感区域和安全操作电压&#xff0c;并提出了辐射损伤…

俊杰测评:电视盒子什么牌子好?电视盒子品牌排行榜

欢迎各位来到俊杰的数码测评频道&#xff0c;每年我会进行数十次电视盒子测评&#xff0c;今年已经买过二十多款电视盒子了&#xff0c;本期的测评主题是电视盒子什么牌子好&#xff0c;通过十天的深入详细对比后我整理了电视盒子品牌排行榜&#xff0c;近期想买电视盒子的可以…

C++运算符

运算符 作用&#xff1a;用于执行代码的运算 本文章主要讲解以下四种运算符&#xff1a; 1.算术运算符 作用&#xff1a;用于处理四则运算 算术运算符包括以下这些符号&#xff1a; 举例&#xff1a; 注&#xff1a; 在除法运算中&#xff0c;除数不能为0 在取模运算…

【MATLAB源码-第194期】基于matlab的MB-OFDM仿真,超宽带(UWB)无线传输。对比LS/DFT及其改进算法。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 一、无线通信的基本原理 无线通信是通过空气或其他介质传播电磁波来传输信息的技术。这种通信方式的核心在于电磁波&#xff0c;它能够在没有物理连接的情况下传输数据。无线通信的基本流程包括&#xff1a; 信号的生成&am…

Redis集合[持续更新]

Redis&#xff08;全称&#xff1a;Remote Dictionary Server 远程字典服务&#xff09;是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库&#xff0c;并提供多种语言的 API。 数据结构 1. string 字符串 字符串类型是 Redis 最…

springboot实现SSE之牛刀小试

文章目录 一&#xff0c;概述1.SSE是何方神圣&#xff1f;2.sse与webscoket区别 二&#xff0c;实现过程1.效果展示2. 简要流程3. 源码放送4.完整项目 一&#xff0c;概述 1.SSE是何方神圣&#xff1f; SSE 全称Server Sent Event&#xff0c;直译一下就是服务器发送事件。 …

FPGA中闪灯程序设计示例

在FPGA设计中&#xff0c;闪灯的作用主要是用于测试和验证设计的功能和性能。具体来说&#xff0c;闪灯可以作为一个可视化的指示器&#xff0c;通过控制LED灯的闪烁模式和频率&#xff0c;来显示FPGA的工作状态或调试信息。 例如&#xff0c;在设计过程中&#xff0c;可以编写…

channel_shuffle代码实现

结构图&#xff0c;先将输入的图像进行通道拆分为组GConv1&#xff0c;每个GConv1再拆分Feature&#xff0c;每个GConv1的Feature进行合并GConv2&#xff0c;输出Output 输入图像x&#xff0c;拆分为groups个组&#xff0c;每隔组的通道数为channels_per_group batch_size, n…

binary tree Leetcode 二叉树算法题

144.二叉树的前序遍历 前序遍历是&#xff1a;根-左-右 所以记录序列的的时候放在最前面 递归 class Solution {List<Integer> ans new ArrayList<>();public List<Integer> preorderTraversal(TreeNode root) {if(root null) return ans;ans.add(root…

请编写函数fun,它的功能是:求出1到1000之内能被7或11整除、但不能同时被7和11整除的所有整数并将它们放在a所指的数组中,通过n返回这些数的个数。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法和详细的解析。 题干 请编写函数fu…

K8S哲学 - Pod、RC、RS、deployment

pod&#xff08;最小的可部署单元&#xff09; 容器组&#xff08;运行一个或多个容器&#xff09; Pod(容器组&#xff09;是Kubernetes 中最小的可部署单元。 一个Pod(容器组&#xff09;包含了一个应用程序容器&#xff08;某些情况下是多个容器&#xff09;、存储资源、 一…

哈尔滨等保测评综述

​ 定级是网络安全等级保护的首要环节和关键环节&#xff0c;可以梳理各行业、各部门、各单位的等级保护对象类型、重要程度和数量等基本信息&#xff0c;确定分级保护的重点。定级不准&#xff0c;系统备案、建设、整改、等级测评等后续工作都会失去意义&#xff0c;等级…

Elastic 网络爬虫:为你的网站添加搜索功能

作者&#xff1a;来自 Elastic Lionel Palacin 为了演示如何使用 Elastic 网络爬虫&#xff0c;我们将以一个具体的网站为例&#xff0c;讲解如何在该网站上添加搜索功能。我们将探讨发现网站的方法&#xff0c;并利用 Elastic 网络爬虫提供的功能&#xff0c;以最佳方式准备待…

LeetCode238 除自身以外数组的乘积

LeetCode238 除自身以外数组的乘积 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 **不要使…

ubuntu下boa服务器编译运行

一.下载boa源码并解压 官网网站&#xff1a;BOA源码 点击箭头所指的位置即可下载 解压&#xff1a; tar -xvf boa-0.94.13.tar.gz 解压完成得到目录&#xff1a; 二.安装环境所缺依赖&#xff0c;否则编译会报错 sudo apt install bison sudo apt install flex 三.编译 1…

基于SSM的养老院管理系统(含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的养老院管理系统4拥有三种角色 管理员&#xff1a;护工\工资\家属\楼房\床位\老人\档案\药品\外出\出入库\缴费\财务\退房管理 家属&#xff1a;填写评价、缴费、查看各种信息 …