题目
题解一:将链表转换为数组,在判断回文
/**
* 将链表数据复制到 数组当中
* @param head
* @return
*/
public static boolean isPalindrome(ListNode head) {
if (head == null||head.next == null) {
return true;
}
//复制数组
List<Integer> nums = new ArrayList<>();
ListNode cur = head;
while (cur!= null){
nums.add(cur.val);
cur = cur.next;
}
//判断回文
int before = 0;
int last = nums.size() -1 ;
while (before < last){
if (nums.get(before).equals(nums.get(last))) {
before++;
last--;
continue;
}else {
return false;
}
}
return true;
}
题解二: 快慢指针
慢指针一次走一步,快指针一次走两步,快慢指针同时出发。当快指针移动到链表的末尾时,慢指针恰好到链表的中间。通过慢指针将链表分为两部分。
/**
* 快慢指针
* @param head
* @return
*/
public static boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode fast = head;//快指针
ListNode slow = head;//慢指针
//寻找最中间的元素 条件是快指针提前走到null
while (fast.next != null&&fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
ListNode la = slow.next;//记录中间节点
//将中间节点往后的元素进行翻转
ListNode reverse = reverse(la);
//将翻转后的链表和前半段对比
while (reverse!=null){
if (reverse.val != head.val ) {
return false;
}
reverse = reverse.next;
head = head.next;
}
return true;
}
//翻转链表
private static ListNode reverse(ListNode head){
// 递归到最后一个节点,返回新的新的头结点
if (head.next == null) {
return head;
}
ListNode newHead = reverse(head.next);
head.next.next = head;
head.next = null;
return newHead;
}