1. 程式人生 > 實用技巧 >常用演算法的總結——連結串列

常用演算法的總結——連結串列

連結串列常用演算法:快慢指標、利用HashMap、棧

如:

1 快慢指標

1) 輸入連結串列頭節點,奇數長度返回中點,偶數長度返回上中點
2) 輸入連結串列頭節點,奇數長度返回中點,偶數長度返回下中點
3) 輸入連結串列頭節點,奇數長度返回中點前一個,偶數長度返回上中點前一個
4) 輸入連結串列頭節點,奇數長度返回中點前一個,偶數長度返回下中點前一個

第一題程式碼如下,其他同理:

// head頭
public static Node mi d0rUpMi dNode(Node head) {
    if (head == nu11|I head.next == nu11Il| head.next.next == nu1l) {
    
return head;
  }   Node slow
= head . next;   Node fast = head. next . next;   while (fast.next != nu11 && fast. next.next != nu11) {     slow = slow. next;     fast = fast. next. next;
  }   
return slow;
}

2給定一個單鏈表的頭節點head,請判斷該連結串列是否為迴文結構。

1) 雜湊表方法特別簡單——利用棧

public static boolean isPalindrome1 (Node head) {
  Stack
<Node> stack = new Stack<Node>( );   Node cur = head;   while (cur != nu1l) {     stack. push(cur);     cur = cur. next;   }   while (head != nu1l) {     if (head.value != stack. pop().value) {       return false;     }     head = head. next;   }   return true; }

2) 改原連結串列的方法就需要注意邊界了

3) 利用快慢指標的演算法:先讓快指標到終點,慢指標到中點,然後讓指向中點的慢指標指向null,後半部分全部倒轉,後面的指向前面的,最後由終點和起點開始往中間遍歷,只要有一步不相等就返回false,最後由如果需要恢復則將其恢復成原樣,程式碼如下(包含了最後恢復成原樣的步驟):

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;//n1move
            n2 = n3;//n2move
        }
        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;

    }