题目描述
给定一个链表的头节点head,请判断该链表是否为回文结构。
例如: 1->2->1,返回true。
1->2->2->1,返回true。
15->6->15,返回true。
1->2->3,返回false。
进阶: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)。
思路
链表相关的问题,笔试时尽快做出来即可,空间复杂度可以高一些;面试时要使空间复杂度低。
方法一:第一遍遍历链表时把值依次压入栈中,第二次遍历链表时,从栈中弹出一个数进行对比,全部一样则是回文结构,否则不是。
方法二:快指针走两步,慢指针走一步,快指针走完时,慢指针到链表中间位置,此时开始压栈,把链表的后半部分压入栈中。然后从头开始遍历链表,同时从栈中弹出节点进行比较,当栈中的数都弹完时,若没有出现不一致的,则是回文结构,否则不是回文结构。
方法三:还是用两个指针,一个一次走一步,一个一次走两步,这样找到中间的节点(奇数个的时候就是最中间的节点,偶数个的时候找到最中间的两个节点中较烤前的那个)。然后把后半段链表逆序,next指针指的方向反过来,中间节点的next指针指向空。接着两个指针从链表的两端开始遍历。
代码
package LinearStructure;
import java.util.Stack;
public class IsPalindromeList {
public static class Node{
public int val;
public Node next;
public Node(int data){ this.val = data; }
}
// 需要n额外空间
public static boolean isPalindromeList1(Node head){
Stack<Node> stack=new Stack<Node>();
Node cur=head;
while (cur != null){
stack.push(cur);
cur=cur.next;
}
while (head != null){
if (head.val != stack.pop().val)
return false;
head=head.next;
}
return true;
}
// 需要2/n额外空间
public static boolean isPalindromeList2(Node head){
if (head == null || head.next == null)
return true;
Node right = head;
Node cur = head;
while (cur.next !=null && cur.next.next!=null){
right=right.next;
cur=cur.next.next;
}
Stack<Node> stack=new Stack<Node>();
while (right!=null){
stack.push(right);
right=right.next;
}
while (!stack.isEmpty()){
if(head.val != stack.pop().val)
return false;
head=head.next;
}
return true;
}
//需要0(1)额外空间
public static boolean isPalindromeList3(Node head){
if (head == null || head.next == null) {
return true;
}
Node n1 = head;
Node n2 = head;
while (n2.next != null && n2.next.next != null) { // find mid node
n1 = n1.next; // n1 -> mid
n2 = n2.next.next; // n2 -> end
}
n2 = n1.next; // n2 -> right part first node
n1.next = null; // mid.next -> null
Node n3 = null;
while (n2 != null) { // right part convert
n3 = n2.next; // n3 -> save next node
n2.next = n1; // next of right node convert
n1 = n2; // n1 move
n2 = n3; // n2 move
}
n3 = n1; // n3 -> save last node
n2 = head;// n2 -> left first node
boolean res = true;
while (n1 != null && n2 != null) { // check palindrome
if (n1.val != n2.val) {
res = false;
break;
}
n1 = n1.next; // left to mid
n2 = n2.next; // right to mid
}
n1 = n3.next;
n3.next = null;
while (n1 != null) { // recover list
n2 = n1.next;
n1.next = n3;
n3 = n1;
n1 = n2;
}
return res;
}
public static void printLinkedList(Node node) {
System.out.print("Linked List: ");
while (node != null) {
System.out.print(node.val + " ");
node = node.next;
}
System.out.println();
}
public static void main(String[] args) {
Node head = null;
printLinkedList(head);
System.out.print(isPalindromeList1(head) + " | ");
System.out.print(isPalindromeList2(head) + " | ");
System.out.println(isPalindromeList3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
printLinkedList(head);
System.out.print(isPalindromeList1(head) + " | ");
System.out.print(isPalindromeList2(head) + " | ");
System.out.println(isPalindromeList3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
printLinkedList(head);
System.out.print(isPalindromeList1(head) + " | ");
System.out.print(isPalindromeList2(head) + " | ");
System.out.println(isPalindromeList3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindromeList1(head) + " | ");
System.out.print(isPalindromeList2(head) + " | ");
System.out.println(isPalindromeList3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
printLinkedList(head);
System.out.print(isPalindromeList1(head) + " | ");
System.out.print(isPalindromeList2(head) + " | ");
System.out.println(isPalindromeList3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindromeList1(head) + " | ");
System.out.print(isPalindromeList2(head) + " | ");
System.out.println(isPalindromeList3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindromeList1(head) + " | ");
System.out.print(isPalindromeList2(head) + " | ");
System.out.println(isPalindromeList3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(2);
head.next.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindromeList1(head) + " | ");
System.out.print(isPalindromeList2(head) + " | ");
System.out.println(isPalindromeList3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindromeList1(head) + " | ");
System.out.print(isPalindromeList2(head) + " | ");
System.out.println(isPalindromeList3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
}
}