1. 程式人生 > >leetcode之環形連結串列

leetcode之環形連結串列

題目描述

  • 給定一個連結串列,判斷連結串列中是否有環。不用額外空間。

題目分析

  • 可以使用快慢指標,快指標比滿指標快一步,如果有環就一定可以追上。如果到達了空指標,說明沒有環。
  • 注意比較相等的時候要比較指標相等,不是節點的值相等。

程式碼

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public
: bool hasCycle(ListNode *head) { // 快慢指標,一個走一步,一個走兩步,如果有環肯定能碰到,如果沒有就最後都指向空。 bool has_cycle = false; if((head == NULL) || (head->next == NULL)){ return false; } ListNode* p1 = head; ListNode* p2 = head; while((p1 != NULL) || (p2 !=
NULL)){ // 往下走一步和兩步 // 如果走到結尾,證明是無環 if(p1->next == NULL){ return false; } else{ p1 = p1->next; } if(p2->next == NULL){ return false; } else
{ p2 = p2->next; } if(p2->next == NULL){ return false; } else{ p2 = p2->next; } if(p1 == p2 ){ return true; } } return false; } };

改進版程式碼:因為快指標走得更快,所以如果沒有環肯定先到達尾部,所以只需判斷快指標是否指向空。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        // 快慢指標,一個走一步,一個走兩步,如果有環肯定能碰到,如果沒有就最後都指向空。
        bool has_cycle = false;
        if((head == NULL) || (head->next == NULL)){
            return false;
        }
        ListNode* p1 = head;
        ListNode* p2 = head;
        // 快指標先到達,所以可以只檢查快指標。
        // 不能先檢查next
        while((p2 != NULL) && (p2->next != NULL)){
            // 往下走一步和兩步
            // 如果走到結尾,證明是無環
            p1 = p1->next;
            p2 = p2->next;
            p2 = p2->next;
            if(p1 == p2){
                return true;
            }
        }
        return false;
    }
};

一個坑: 判斷指標的是否不能先判斷next,有可能快指標已經指向了空。

總結

一到快慢指標典型的題目。