问题:
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
思路:利用数组的方式
1.当链表为空时,直接返回true;
2.创建一个数组,当head != null的时候,将链表中的元素逐一放进数组中
3.设置两个标志位,分别为数组头和数组尾。
3.while(a < b)的时候,利用arr.get(a).comparTo()方法来比较元素的值是否相同.
4.直到while(a < b)条件不成立,跳出循环,说明一直到两个标志位相遇之前的所有元素均相同,所以链表为回文链表。
完整代码:
import java.util.ArrayList;
class Solution {
public boolean isPalindrome(ListNode head) {
ArrayList<Integer> arr = new ArrayList<Integer>();
if(head == null || head.next == null){
return true;
}
while(head !=null){
arr.add(head.val);
head = head.next;
}
int a = 0;
int b = arr.size() - 1;
while(a < b){
if(arr.get(a).compareTo(arr.get(b)) != 0){
return false;
}
++a;
--b;
}
return true;
}
}
思路二:利用双指针+反转链表的方式
1.设置一个虚拟头结点,
2.设置两个快慢指针,快指针一次移动两个节点,慢指针一次移动一个节点,当快指针的下一个节点为空的时候停止移动,此时,慢指针的位置即为整个链表的中间。
3.反转后半部分的链表
4.对比反转后的链表的每一个节点的值是否相等
完整代码:
class Solution {
public boolean isPalindrome(ListNode head) {
//边界条件不用忘记了
if(head==null || head.next==null) {
return true;
}
ListNode p = new ListNode(-1);
ListNode low = p;
ListNode fast = p;
p.next = head;
//快慢指针不断迭代,找到中间节点
while(fast!=null && fast.next!=null) {
low = low.next;
fast = fast.next.next;
}
ListNode cur = low.next;
ListNode pre = null;
low.next = null;
low = p.next;
//将链表一分为二之后,反转链表后半部分
while(cur!=null) {
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
//将链表前半部分和 反转的后半部分对比
while(pre!=null) {
if(low.val!=pre.val) {
return false;
}
low = low.next;
pre = pre.next;
}
return true;
}
}