leetcode之環形連結串列
阿新 • • 發佈:2018-12-31
題目描述
- 給定一個連結串列,判斷連結串列中是否有環。不用額外空間。
題目分析
- 可以使用快慢指標,快指標比滿指標快一步,如果有環就一定可以追上。如果到達了空指標,說明沒有環。
- 注意比較相等的時候要比較指標相等,不是節點的值相等。
程式碼
/**
* 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,有可能快指標已經指向了空。
總結
一到快慢指標典型的題目。