1. 反转链表

  1. //pre 指向前一个节点,cur 指向当前正在处理的节点,temp 暂存下一个节点
  2. ListNode* reverse(ListNode* head){
  3. ListNode* pre = nullptr, *cur = head, *temp;
  4. while(cur){
  5. temp = cur->next;
  6. cur->next = pre;
  7. pre = cur;
  8. cur = temp;
  9. }
  10. return pre;
  11. }
  1. ListNode* reverse(ListNode* head){
  2. if (!head || !(head->next))
  3. return head;
  4. ListNode* newHead = reverse(head->next);
  5. head->next->next = head;
  6. head->next = nullptr
  7. return newHead;
  8. }

2. 判断链表中是否存在环

  1. //快指针每次前进两个单位,慢指针每次前进一个单位,
  2. //如果链表中存在环则快慢指针一定会相遇 (尚不明白原理)
  3. bool hasCycle(ListNode *head) {
  4. ListNode* slow, *fast;
  5. slow = fast = head;
  6. //没有环时快指针到达链表末尾
  7. while(fast && fast->next){
  8. fast = fast->next->next;
  9. slow = slow->next;
  10. if (fast == slow) return true;
  11. }
  12. return false;
  13. }
  1. //每次将当前节点的next指向自己,相当于从链表中删除自己,
  2. //如果最后遍历到了next指向自己的节点,则有两种可能:
  3. //1. 链表中原本就存在next指向自己的节点,判断为有环
  4. //2. 该节点是处理过后才指向自己,则代表有后面的节点指向前面的节点,判断为有环
  5. bool hasCycle(ListNode *head) {
  6. ListNode* p = head, *next;
  7. // p == nullptr 时表示链表无环
  8. while(p){
  9. //判断是否有环,同时如果判断成功则 p 为环的入口
  10. if (p->next == p) return true;
  11. //从链表中删除当前节点
  12. next = p->next;
  13. p->next = p;
  14. p = next;
  15. }
  16. return false;
  17. }

3. 指出链表中环的起点

  1. //前半部分就是上面判断是否存在环的代码
  2. //判断存在环后,将快指针移至链表头,将快慢指针同时后移一位直至相遇,
  3. //该节点则为环的入口
  4. ListNode* EntryNodeOfLoop(ListNode* pHead) {
  5. //快慢指针判断环,同上
  6. ListNode* fast = pHead, *slow = pHead;
  7. while(fast && fast->next){
  8. fast = fast->next->next;
  9. slow = slow->next;
  10. if (fast == slow) break;
  11. }
  12. //不存在环的情况,注意还要判断 fast->next
  13. if (!fast || !(fast->next)) return nullptr;
  14. //寻找环的起点
  15. fast = pHead;
  16. while(fast != slow){
  17. fast = fast->next;
  18. slow = slow->next;
  19. }
  20. return fast;
  21. }

判断是否存在环中的逐个删除方法也可用来解此题,但实测效率不如快慢指针