leetcode 题号#234 回文链表

2024-06-09 09:48

本文主要是介绍leetcode 题号#234 回文链表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

查看题目详情可点击此处。

题目

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true

解题思路

首先理解回文的意思,回文就是正着读和反着读得到的结果都一样,那最直接的解题思路就是拷贝一份反转的链表,再与原链表从头结点开始比对,如果完全一致就是回文链表,但空间复杂度和时间复杂度都为 O ( n ) O(n) O(n),为了把空间复杂度降低需要重新转换思路。

仔细思考,其实回文还有另外一种判断方式,就是从中间结点往头结点和尾结点方向读取,得到的结果是一样的,但题目给出的是单链表,如果是双向链表操作就会简单很多,单链表的情况只能把前半段链表反转,以中间结点作为头结点,头结点为前半段的尾结点,后半段链表也以中间结点为头结点,尾结点作为尾结点,这样循环比对每个结点,就可以判断回文。

要知晓链表的中间结点只能先获取整个链表的长度,奇数长度的链表中间结点分别是第 n / 2 n/2 n/2 n / 2 + 2 n/2+2 n/2+2个结点,偶数结点的中间结点分别是第 n / 2 n/2 n/2 n / 2 + 1 n/2+1 n/2+1个结点,得知中间结点的是链表中的第几个结点后,可以遍历获取中间结点作为头结点的同时对前半段链表进行反转,最后进行相应链表结点的比对即可,代码如下。

class Solution {public boolean isPalindrome(ListNode head) {if(head == null || head.next == null) {return true;}int len = getLinkLen(head);int leftHeadCounter = len / 2;ListNode[] halfHeads = findHalfHead(head, leftHeadCounter, len);ListNode leftHalfHead = halfHeads[0];ListNode rightHalfHead = halfHeads[1];ListNode leftCurr = leftHalfHead;ListNode rightCurr = rightHalfHead;while(leftCurr != null && rightCurr != null) {if(leftCurr.val != rightCurr.val) {break;}leftCurr = leftCurr.next;rightCurr = rightCurr.next;}return leftCurr == null && rightCurr == null;}public ListNode[] findHalfHead(ListNode head, int leftHeadCounter, int len) {ListNode[] halfHeads = new ListNode[2];ListNode curr = head;ListNode prevNode = null;ListNode reverseNode = null;int counter = 0;while(curr != null) {counter++;if(leftHeadCounter == counter) {halfHeads[0] = curr;break;}reverseNode = curr;curr = curr.next;prevNode = reverseLink(reverseNode, prevNode);}ListNode rightHalfHead = halfHeads[0].next;if(len % 2 == 1) {rightHalfHead = rightHalfHead.next;}halfHeads[1] = rightHalfHead;reverseLink(halfHeads[0], prevNode);return halfHeads;}public ListNode reverseLink(ListNode reverseNode, ListNode prevNode) {reverseNode.next = prevNode;return reverseNode;}public int getLinkLen(ListNode head) {int len = 0;ListNode curr = head;while(curr != null) {len++;curr = curr.next;}return len;}
}

这篇关于leetcode 题号#234 回文链表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1044834

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

csu1328(近似回文串)

题意:求近似回文串的最大长度,串长度为1000。 解题思路:以某点为中心,向左右两边扩展,注意奇偶分开讨论,暴力解即可。时间复杂度O(n^2); 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>#include<string>#inclu

csu1329(双向链表)

题意:给n个盒子,编号为1到n,四个操作:1、将x盒子移到y的左边;2、将x盒子移到y的右边;3、交换x和y盒子的位置;4、将所有的盒子反过来放。 思路分析:用双向链表解决。每个操作的时间复杂度为O(1),用数组来模拟链表,下面的代码是参考刘老师的标程写的。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

深入手撕链表

链表 分类概念单链表增尾插头插插入 删尾删头删删除 查完整实现带头不带头 双向链表初始化增尾插头插插入 删查完整代码 数组 分类 #mermaid-svg-qKD178fTiiaYeKjl {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

建立升序链表

题目1181:遍历链表 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2744 解决:1186 题目描述: 建立一个升序链表并遍历输出。 输入: 输入的每个案例中第一行包括1个整数:n(1<=n<=1000),接下来的一行包括n个整数。 输出: 可能有多组测试数据,对于每组数据, 将n个整数建立升序链表,之后遍历链表并输出。 样例输

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点