package basic_class_03;
import java.util.Stack;
/**
* 判断一个链表是否为回文结构
* @author lenovo
*
*/
public class Code_11_IsPalindromeList {
public static class Node {
public int value;
public Node next;
public Node(int data) {
this.value = data;
}
}
// 需要 n 的额外空间
// 使用栈
public static boolean isPalindrome1(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.value != stack.pop().value) {
return false;
}
head = head.next;
}
return true;
}
// 需要 n/2 的额外空间
// 使用中点 + 栈
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; // 一次走两步
}
// 上面过程结束之后 ,right就是指向 中点的后一位 如果是偶数个数的话,那么就是指向后半段的第一个位置
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;
}
// 需要 O(1) 的额外空间
// 不使用栈
public static boolean isPalindrome3_1(Node head) {
if(head == null || head.next == null) {
return true;
}
Node n1 = head;
Node n2 = head;
while(n2.next != null && n2.next.next != null) {
n1 = head.next;
n2 = head.next.next;
}
// 现在 n1 指向的是中点位置
n2 = n1.next; // n2 现在指向的是右半部分的第一个节点
n1.next = null; // 现在整个链表就被 分成左半部分跟右半部分链表
// 奇数 : 1 -> 2 -> 3 <- 4 <- 5 <- 6
// 偶数 : 1 -> 2 -> 3 -> 4 <- 5 <- 6 <- 7
Node n3 = null; // n3 是辅助用的 这个节点到时需要用来恢复这个不是正常顺序的链表
while(n2 != null) { // 这一步是将右半部分的链表进行反转
n3 = n2.next;
n2.next = n1;
n1 = n2; // 这个 n1 现在是指向了最后一个节点 (代表的是右半部分的节点链表的首个节点)
n2 = n3;
}
n3 = n1; // n3 跟 n1 一样指向的是最后一个节点 这里的意义实际是为了保存关系
n2 = head; // n2指向的是头节点
// 现在这个链表就可以看成两个部分 :
// 左半部分 n2
// 右半部分 n1
boolean res = true;
while(n1 != null && n2 != null) {
if(n1.value != n2.value) {
res = false;
break; // 不能直接就返回false 因为还需要对乱的链表进行恢复
}
n1 = n1.next;
n2 = n2.next;
}
// 判断回文完毕 接下来就是要将破坏了顺序的链表进行恢复了
n1 = n3.next;
n3.next = null;
while(n1 != null) {
n2 = n1.next;
n1.next = n3;
n3 = n1;
n1 = n2;
}
return res;
}
}
判断一个链表是否为回文结构 -- 三种实现方式 -- 由易到难
猜你喜欢
转载自blog.csdn.net/qq_38200548/article/details/81287126
今日推荐
周排行