判断是否为回文
思路一:利用现成的栈,全部或折半push压栈,依次弹栈pop比对,但会有额外的空间开销
思路二:快慢指针解决
1.使用快慢指针找到链表的中点
2.逆序链表的后一半(只要fast != null就不停)
3.头尾节点比对并向中点移动(只有要一个的next为null,则结束)
4.恢复链表
======================================================================
1 1 1 1 :慢指针 slow
0 0 0 0 0 0 0 0 :链表
1 1 1 1 :快指针 fast
======================================================================
package com.kali.link.subject;
import com.kali.link.MyLinked;
import com.kali.link.Node;
/**
* 题目:判断是否问回文
* 1.使用压栈,压后半
* 2.使用快慢指针
*
* 为什么链表需要快慢指针呢?链表的长度"不好"确定
*
*/
public class Linked_palindrome {
public static void main(String[] args) {
int[] arr = {23,12,1,1,12,23,2};
MyLinked link = new MyLinked();
link.add(arr);
link.print();
Node head = link.getHead();
System.out.println("\n" + isPalindrome(head));
}
/*
1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1
*/
public static boolean isPalindrome(Node head){
if(head == null || head.next == null){
return true;
}
Node slow = head;
Node fast = head;
/*slow -> mid fast -> end*/
while(fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
/*right part convert*/
fast = slow.next;
slow.next = null;
Node hook = null;
while (fast != null){
hook = fast.next;//save next node
fast.next = slow;
slow = fast;//slow moved to last node
fast = hook;
}
/*use hook pointer save last node,fast save first node,slow is last node*/
hook = slow;
fast = head;
/*any one is not equal,break*/
boolean flag = true;
while (slow != null && fast != null){
if(slow.val != fast.val){
flag = false;
break;
}
slow = slow.next;
fast = fast.next;
}
/*recover link*/
fast = hook.next;//save last.next node
hook.next = null;//reset last.next is null
while(fast != null){
slow = fast.next;
fast.next = hook;
hook = fast;
fast = slow;
}
return flag;
}
}