1. 程式人生 > 其它 >迴文連結串列的判斷

迴文連結串列的判斷

前置知識點:

棧的使用:

 1 import java.util.Stack;    //引用棧
 2 //初始化
 3 Stack<Integer> stack = new Stack<Integer>();
 4 //進棧
 5 stack.push(Element);
 6 //出棧
 7 stack.pop();
 8 //取棧頂值(不出棧)
 9 stack.peek();
10 //判斷棧是否為空
11 stack.isEmpty()

 

1.利用棧的方法來實現判斷迴文連結串列(需要額外的空間):

 1 /*
 2      * 方法一:
 3      * 通過額外的棧空間來判斷是否為迴文連結串列(利用棧後進先出的特點,正好出棧得到連結串列的逆序)
4 * 但是需要額外的O(n)空間 5 */ 6 @SuppressWarnings("null") 7 public static boolean IsPalinList1(MyLink list) { 8 Stack<Integer> sk = new Stack<>(); 9 Node head = list.head; 10 Node p = head; 11 while (p != null) { 12 sk.push(p.num);
13 p = p.next; 14 } 15 p = head; 16 while (p != null) { 17 if (p.num != sk.peek()) { 18 return false; 19 } 20 sk.pop(); 21 p = p.next; 22 } 23 return true; 24 }

 

2.不開闢額外空間,直接用本身的特點來實現判斷

 1 /*
 2      * 方法二:
 3      * 直接通過連結串列本身進行判斷
 4      * 找到連結串列的中點處,把中點往右的連結串列翻轉,然後分別從最左端和最右端開始逐一比對,直到比對到中間為止
 5      */
 6     public static boolean IsPalinList2(MyLink list) {
 7         Node head = list.head;
 8         if (head.next == null) {
 9             return true;
10         }
11         //用快指標和慢指標來確定中點位置
12         //(當快指標要到末尾時,慢指標處在中點位置(長度為奇偶數分情況討論,根據題目要求進行微調))
13         Node fast = head, slow = head;
14         boolean isPalinList = true;
15         while (fast.next != null && fast.next.next != null) {
16             fast = fast.next.next;
17             slow = slow.next;
18         }
19         //從slow處的後一個開始翻轉連結串列
20         Node p = slow.next;
21         boolean needReverse = true;
22         if (p.next == null) {//如果後面只有一項則無需翻轉
23             needReverse = false;
24         }
25         if (needReverse == true) {
26             Node q = p.next, r = q.next;
27             p.next = null;
28             while (q != null) {
29                 q.next = p;
30                 p = q;
31                 q = r;
32                 if (r != null) {
33                     r = r.next;
34                 }
35             }
36         }
37         Node revHead = p;
38         //此時已經成功翻轉後半部分連結串列,開始進行比對
39         Node t1 = head, t2 = revHead;
40         while (t2 != null) {//此處用t2,因為在奇數情況下,中間值不用比,而正向比反向多一箇中間值
41                             //(所以 以反向作為結束判斷)
42             if (t1.num != t2.num) {
43                 isPalinList = false;
44                 break;
45             }
46             t1 = t1.next;
47             t2 = t2.next;
48         }
49         //把連結串列恢復原狀(即把之前翻轉的那部分翻轉回來即可)
50         if (needReverse == true) {//如果之前有翻轉過
51             Node a = revHead;
52             Node b = a.next, c = b.next; 
53             a.next = null;
54             while (b != null) {
55                 b.next = a;
56                 a = b;
57                 b = c;
58                 if (c != null) {
59                     c = c.next;
60                 }
61             }
62         }
63         if (isPalinList == true) {
64             return true;
65         }
66         else {
67             return false;
68         }
69     }