單鏈表的回文判斷(O(n)時間復雜度和O(1)的空間復雜度)


對於單鏈表來說,判斷回文最簡單的方法就是遍歷鏈表,將鏈表中的元素復制到數組中,然后對數組進行判斷是否是回文數組,但是這不符合O(1)的空間復雜度。

由於空間復雜度的要求,需要就地操作鏈表,不能開辟多余的空間來進行處理,因此引入快慢指針來進行操作。

快慢指針: slow 和 fast,每次slow指針前進一步,fast指針前進兩步,當遇到指針為空時說明遍歷鏈表完成,此時也就可以找到鏈表的中心位置。

注意,由於鏈表的長度可能是奇數也可能是偶數,因此應該做一個判斷。

找到鏈表的中心后,把鏈表的后半部分進行就地逆轉,就地逆轉是采用頭插法即可。

后半部分逆轉完成后,將鏈表的前半部分和后半部分一次比較,即可判斷是否是回文。

實現代碼如下:

鏈表類定義:

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { 
      val = x; 
    }

}

 

 

鏈表就地反轉:

public static ListNode reverseList(ListNode head){
   ListNode ptr = head, ptr2 = head;
   ListNode fast = head.next;
   while(fast!=null){

       //頭插法
       ptr = fast.next;
       fast.next = head;
       head = fast;
       fast = ptr;
  }

  //反轉完成后將原頭指針的next設置為null
  ptr2.next = null; 
  return head;
}

 

判斷鏈表是否是回文:

 1 public static boolean isPalindrome(ListNode head){
 2 if(head==null || head.next==null){
 3 return true;
 4 }
 5 //建立快慢指針,尋找鏈表中心
 6 ListNode slow = head;
 7 ListNode fast = head;
 8 while(fast!=null && fast.next!=null){
 9 slow = slow.next;
10 fast = fast.next.next;
11 }
12 
13 if(fast == null){
14 //偶數個元素(進行鏈表反轉)
15 ListNode ptr = slow, ptr2 = slow;
16 ListNode fast1 = slow.next;
17 while(fast1!=null){
18 ptr = fast1.next;
19 fast1.next = slow;
20 slow = fast1;
21 fast1 = ptr;
22 }
23 ptr2.next = null;
24 }else{
25 //奇數個元素(進行鏈表反轉)
26 ListNode ptr = slow.next,ptr2 = slow.next;
27 ListNode fast1 = slow.next.next;
28 while(fast1 != null){
29 ptr = fast1.next;
30 fast1.next = slow.next;
31 slow.next = fast1;
32 fast1 = ptr;
33 }
34 ptr2.next = null;
35 slow = slow.next;
36 }
37 
38 while(slow!=null){
39 if(head.val!=slow.val)
40 return false;
41 slow = slow.next;
42 head = head.next;
43 }
44 return true;
45 }
46 
47 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM