题目
请判断一个链表是否为回文链表。
用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题
示例
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
思路
首先使用快慢指针找到链表中点,然后翻转后半部分链表,再与前半部分对比。
翻转链表请看:翻转链表。
快慢指针:
快慢指针是指使用两个指针slow和fast,slow每次走一步,fast每次走两步(我不知道有没有其他快慢指针是走不是两步的,不过这道题是)。你会发现fast走到最后的时候,slow刚好走到中点。
例如链表:1->2->3->4->5->6->7->8->9
slow=1,fast=1
slow=2,fast=3
slow=3,fast=5
slow=4,fast=7
slow=5,fast=9(fast走到最后,停止循环)
所以5就是我们的中点,返回看链表也的确如此。
代码
public class problem234 {
public static class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
// 传入数组,生成链表
public ListNode createList(int[] num) {
if (num.length == 0)
return null;
ListNode head = new ListNode(num[0]);
ListNode res = head;
for (int i = 1; i < num.length; i++) {
head.next = new ListNode(num[i]);
head = head.next;
}
return res;
}
// 迭代反转链表
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
ListNode temp;
while (cur != null) {
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
public boolean isPalindrome(ListNode head) {
if(head==null||head.next==null)
return true;
//快慢指针找中点
ListNode slow=head;
ListNode fast=head;
while(fast.next!=null&&fast.next.next!=null){
slow=slow.next;
fast=fast.next.next;
}
ListNode mid=reverseList(slow.next);
while(head!=null&&mid!=null){
if(head.val==mid.val){
head=head.next;
mid=mid.next;
}else{
return false;
}
}
return true;
}
public static void main(String[] args) {
problem234 pro = new problem234();
int num[] = { 1, 2, 2, 1 };
System.out.println(pro.isPalindrome(pro.createList(num)));
}
}