LeetCode

链表求环

2018-03-07  本文已影响0人  徐凯_xp

LeetCode 141. Linked List Cycle 142.Linked List Cycle II

已知链表中可能存在环,若有环返回环起始节点,否则返回NULL。


算法1:使用set求环起始节点

1.遍历链表,将链表中节点对应的指针(地址),插入set
2.在遍历时插入节点前,需要在set中查找,第一个在set中发现的节点地址,即是链表环的起点。


class Solution{
public:
    ListNode * detectCycle(ListNode *head){
    std:: set<ListNode *> node_set;//设置node_set
    while(head){
    if(node_set.find(head) != node_set.end()){
    return head;
}
node_set.insert(head);//将节点插入node_set
head = head->next;
}
return NULL;//没有遇到环,则返回NULL
}
}
算法2:快慢指针赛跑




结论:从head和meet出发,两指针速度一样,相遇时即为环的起点
class Solution{
public:
    ListNode * detectCycle(ListNode *head){
    ListNode *fast = head;//快慢指针
    ListNode *slow = head;
    ListNode *meet = NULL;
    while(fast){
    slow = slow->next;
    fast = fast->next;
    if(!fast){
        return NULL;//如果遇到链表尾,返回NULL
    }
fast = fast->next;
   if(fast ==  slow){
      meet = fast;  
      break;
  }
}
if(meet == NULL){
  return NULL;  
}
while(head && meet){
    if(head == meet){
        return head;    
}
head = head->next;
meet = meet->next;
}
return NULL;
}

};
测试与Leetcode提交结果
int main(){
  ListNode a(1);
  ListNode b(2);
  ListNode c(3);
  ListNode d(4);
  ListNode e(5);
  ListNode f(6);
  ListNode g(7);
  a.next = &b;
  b.next = &c;
  c.next = &d;
  d.next = &e;
  e.next = &f;
  f.next = &g;
  g.next =&c;
  Solution solve;
  ListNode *node = solve.detectCycle(&a);
  if(node){
    printf("%d\n",node->val);
  else{
      printf("NULL\n");
  }  
return 0;
}

}
上一篇下一篇

猜你喜欢

热点阅读