【题目】给定一个单链表的头节点head,请判断该链表是否为回文结构。 【例子】1->2->1,返回true;1->2->2->1,返回true;15->6->15,返回true;1->2->3,返回false。 【例子】如果链表长度为N,时间复杂度达到0(N),额外空间复杂度达到0(1)。
package Algorithms; /** * @author : zhang * @version : 1.0 * @date : Create in 2021/8/10 * @description : */ import java.util.Stack; public class IsPalindromeList { public static class Node { public int value; public Node next; public Node(int data) { this.value = data; } } // need n extra space 笔试用此种方法 public static boolean isPalindrome1(Node head) { Stack<Node> stack = new Stack<>(); Node cur = head; while(cur!=null){ stack.push(cur); cur=cur.next; } while(head!=null){ if (head.value!=stack.pop().value){ return false; } head = head.next; } return true; } // need n/2 extra space 快慢指针:cur走1步,right走两步 public static boolean isPalindrome2(Node head) { if (head == null || head.next == null) { return true; } Node right = head.next; 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.value != stack.pop().value) { return false; } head = head.next; } return true; } // need O(1) extra space 面试用此方法回答(使用有限的几个变量解决) //过程举例:将 1 -> 2 -> 3 -> 2 -> 1 变为:1 -> 2 -> 3 <- 2 <- 1 进行比较 //最后再变为1 -> 2 -> 3 -> 2 -> 1返回true public static boolean isPalindrome3(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.value != n2.value) { 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.value + " "); node = node.next; } System.out.println(); } public static void main(String[] args) { Node 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(isPalindrome1(head) + " | "); System.out.print(isPalindrome2(head) + " | "); System.out.println(isPalindrome3(head) + " | "); printLinkedList(head); } } /** * Linked List: 1 2 3 2 1 * true | true | true | * Linked List: 1 2 3 2 1 */