题目 给定一个链表的头节点head,请判断该链表是否为回 文结构。 例如: 1->2->1,返回true。 1->2->2->1,返回true。 15->6->15,返回true。 1->2->3,返回false。
进阶 如果链表长度为N,时间复杂度达到O(N),额外空间复杂 度达到O(1)。
思路 (1)额外空间复杂度O(N):将链表的值依次压栈,然后依次弹出并与原链表逐个比较;
(2)额外空间复杂度O(N/2):设置两个指针p,q,其中p一次走一步,q一次走两步,待q遍历到最后p便位于链表中间,然后将链表后半部分一次压栈,然后依次弹出与前半部分链表进行比较;
(3)额外空间复杂度O(1):设置两个指针p,q,其中p一次走一步,q一次走两步,待q遍历到最后p便位于链表中间,然后将链表后半部分数值进行反转【也就是反转单向链表结构操作】,从两头开始遍历并逐个比较。
package algorithm.section4;
import java.util.Stack;
public class IsPalindromeList {
public static class Node{
int value;
Node next;
public Node(int value){
this.value = value;
}
}
public static boolean method1(Node head){
if (head == null || head.next == null) return true;
Stack<Integer> flag = new Stack<Integer>();
Node p = head;
while (p != null){
flag.push(p.value);
p = p.next;
}
while (!flag.isEmpty()){
if (head.value != flag.pop())
return false;
head = head.next;
}
return true;
}
public static boolean method2(Node head){
if (head == null || head.next == null) return true;
Node p = head;
Node q = head;
while (q.next != null && q.next.next != null){
p = p.next;
q = q.next.next;
}
Stack<Integer> flag = new Stack<Integer>();
Node p0 = p;
while (p.next != null){
flag.push(p.next.value);
p = p.next;
}
while (!flag.isEmpty()){
if (head.value != flag.pop())
return false;
head = head.next;
}
return true;
}
public static boolean method3(Node head){
if (head == null || head.next == null) return true;
Node p = head;
Node q = head;
while (q.next != null && q.next.next != null){
p = p.next;
q = q.next.next;
}
Node p0 = p.next;
p.next = null;
while (p0 != null){
q = p0.next;
p0.next = p;
p = p0;
p0 = q;
}
p0 = p;
p = head;
while (p != null && p0 != null){
if (p.value != p0.value)
return false;
p = p.next;
p0 = p0.next;
}
return true;
}
public static void main(String[] args){
Node head = null;
System.out.print(method1(head) + " | ");
System.out.print(method2(head) + " | ");
System.out.println(method3(head) + " | ");
System.out.println("=========================");
head = new Node(1);
System.out.print(method1(head) + " | ");
System.out.print(method2(head) + " | ");
System.out.println(method3(head) + " | ");
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
System.out.print(method1(head) + " | ");
System.out.print(method2(head) + " | ");
System.out.println(method3(head) + " | ");
System.out.println("=========================");
head = new Node(1);
head.next = new Node(1);
System.out.print(method1(head) + " | ");
System.out.print(method2(head) + " | ");
System.out.println(method3(head) + " | ");
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
System.out.print(method1(head) + " | ");
System.out.print(method2(head) + " | ");
System.out.println(method3(head) + " | ");
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(1);
System.out.print(method1(head) + " | ");
System.out.print(method2(head) + " | ");
System.out.println(method3(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);
System.out.print(method1(head) + " | ");
System.out.print(method2(head) + " | ");
System.out.println(method3(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);
System.out.print(method1(head) + " | ");
System.out.print(method2(head) + " | ");
System.out.println(method3(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);
System.out.print(method1(head) + " | ");
System.out.print(method2(head) + " | ");
System.out.println(method3(head) + " | ");
System.out.println("=========================");
}
}