题目
给定一个链表,请判断该链表是否为回文结构。回文是指该字符串正序逆序完全一致。
数据范围: 链表节点数 0≤n≤10^5,链表中每个节点的值满足 ∣val∣≤10^7。
示例1
输入:{1}
返回值:true
示例2
输入:{2,1}
返回值:false
说明:2->1
示例3
输入:{1,2,2,1}
返回值:true
说明:1->2->2->1
思路1
因为需要判断是否为回文结构,所以要比较头尾的数据,而链表无法随机查询数据,所以可以先将链表转换成list。
具体步骤:
- 首先初始化一个list列表;
- 遍历链表,将链表中的值转移至list中;
- 在list中通过比较头尾的值来判断链表是否为回文结构。
代码1
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类 the head
* @return bool布尔型
*/
public boolean isPail (ListNode head) {
// write code here
//1.边界条件判断
//当链表中没有节点或只有一个节点时,是回文结构
if(head == null || head.next == null){
return true;
}
//2.初始化一个list列表
List<Integer> nums = new ArrayList<Integer>();
//3.遍历链表,将链表中的值转移至list中
while(head != null){
nums.add(head.val);
head = head.next;
}
//4.在list中通过比较头尾的值来判断链表是否为回文结构
int i = 0;
int j = nums.size() - 1;
while(i < j){
//不等则返回false
//注意:如果不使用equals()方法而使用!=的话,在牛客上对于有负数的测试用例可能会无法通过
if(!nums.get(i).equals(nums.get(j))){
return false;
}
++i;
--j;
}
return true;
}
}
- 时间复杂度:O(n),两次遍历;
- 空间复杂度:O(n),列表存储数据需要的size为n。
思路2
方法一的空间复杂度为O(n),较大。
优化:可以使用快慢指针,快指针的速度为慢指针的两倍,当快指针到达链表尾部时,慢指针到达中间位置,将慢指针之后的部分进行反转,再与前半部分进行比较。
代码2
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类 the head
* @return bool布尔型
*/
public boolean isPail (ListNode head) {
// write code here
//定义快慢指针
ListNode fast = head, slow = head;
//快指针速度为慢指针速度的2倍
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
//当快指针到达链表尾部时,慢指针到达链表中间位置
//如果fast不为空,说明链表的长度是奇数个
//例:1 -> 2 -> 3 -> 4 -> 5
// fast
// slow
// fast
// slow
// fast
// slow
//此时fast.next == null,终止遍历
//此时fast!=null,说明链表长度为奇数
if (fast != null) {
slow = slow.next;
}
//此时慢指针到达中间位置
//反转后半部分链表
slow = reverse(slow);
//将后半部分反转后的链表与前半部分链表进行比较
fast = head;
while (slow != null) {
//比较,判断节点值是否相等
if (fast.val != slow.val) {
return false;
}
fast = fast.next;
slow = slow.next;
}
return true;
}
//反转链表
public ListNode reverse(ListNode head) {
ListNode prev = null;
while (head != null) {
ListNode next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}
}