ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LeetCode快慢指针

2022-07-01 18:34:40  阅读:194  来源: 互联网

标签:快慢 head slow ListNode nullptr fast next LeetCode 指针


Add Two Numbers

LeetCode/力扣

  • 模拟两个数相加
  • 用一个数表示进位
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode *t1 = l1, *t2 = l2;
    int n1 = 0, n2 = 0, c = 0;
    ListNode *prev = nullptr;
    while(t1 && t2) {
        int sum = t1->val + t2 -> val + c;
        t1->val = t2 -> val = sum % 10;
        c = sum / 10;
        n1++; n2++;
        prev = t1;
        t1 = t1 -> next; t2 = t2 -> next;
    }
    while(t1) {
        int sum = t1 -> val + c;
        t1 -> val = sum % 10;
        c = sum / 10;
        n1++;
        prev = t1;
        t1 = t1 -> next;
    }
    while(t2) {
        int sum = t2 -> val + c;
        t2 -> val = sum % 10;
        c = sum / 10;
        n2++;
        prev = t2;
        t2 = t2 -> next;
    }
    if (c > 0) {
        ListNode *cry = new ListNode(c);
        prev->next = cry;
    }
    return n1 >= n2 ? l1 : l2;
}

Remove Nth Node From End of List

LeetCode/力扣

  • 一个指针先向前移动n - 1长度
  • 然后两个指针一起移动
  • 直到第一个指针移动到了末尾
  • 慢指针后面那个就是要被移除的,执行删除即可
ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode* p = new ListNode(0);
    p->next = head;
    if(n <= 0) return head;
    ListNode *fast = p, *slow = p;
    for(int i = 0; i < n && fast != nullptr; i++) {
        fast = fast -> next;
    }
    while(fast != nullptr && fast -> next != nullptr) {
        fast = fast -> next;
        slow = slow -> next;
    }
    slow -> next = slow -> next == nullptr ? nullptr : slow -> next -> next;
    return p -> next;
}

Remove Duplicates from Sorted List

LeetCode/力扣

  • 两个指针移动
  • 如果两个指针值相同, 直接把slow指针的next指向fast的next
  • 否则 slow = fast,fast = fast -> next
ListNode* deleteDuplicates(ListNode* head) {
    if(head == nullptr) return head;
    ListNode *left = head, *right = head -> next;

    while(right != nullptr) {
        if(left -> val == right -> val) {
            left - > next = right -> next;
        } else {
            left = right;
        }
        right = right -> next;
    }
    return head;
}

Linked List Cycle

LeetCode/力扣

  • 快指针走两步, 慢指针走一步
  • 如果慢指针追上了快指针,则有环
  • 否则,无环
bool hasCycle(ListNode* head) {
    if(head == nullptr || head -> next == nullptr) return false;
    ListNode *fast = head -> next, *slow = head;

    while(fast != nullptr && fast -> next != nullptr && slow != nullptr) {
        if (fast == slow) return true;
        fast = fast -> next -> next;
        slow = slow -> next;
    }
    return false;
}

Linked List Cycle II

LeetCode/力扣

  • 先用快慢指针找到两个相等的位置
  • 然后慢指针从头开始走, 快指针继续走
  • 两者再次相遇的地方就是环开始的地方
  • 否则就没有环
ListNode* detectCycle(ListNode* head) {
    if(head == nullptr || head -> next == nullptr) return nullptr;
    ListNode *slow = head, *fast = head;

    do {
        if(fast == nullptr || fast -> next == nullptr) return nullptr;
        slow = slow -> next;
        fast = fast -> next -> next;
    } while(fast != slow)
    slow = head;
    while(fast != slow && fast != nullptr && slow != nullptr) {
        slow = slow -> next;
        fast = fast -> next;
    }
    return slow;
}

Reorder List

LeetCode/力扣

  • 先用快慢指针找到中点位置
  • 然后后半部分链表翻转
  • 最后两个链表合并
ListNode* reverse(ListNode* head) {
    ListNode *prev = nullptr, *cur = head;
    while(cur != nullptr) {
        ListNode* next = cur -> next;
        cur -> next = prev;
        prev = cur;
        cur = next;
    }
    return prev;
}
void recorderList(ListNode* head) {
    if(head == nullptr || head -> next != nullptr) return;
    ListNode *slow = head, *fast = head -> next;
    while(fast != nullptr && fast -> next != nullptr) {
        slow = slow -> next;
        fast = fast -> next;
    }
    fast = reverse(slow);
    slow = head;
    while(fast != nullptr && slow != nullptr) {
        ListNode* st = slow -> next, *ft = fast -> next;
        slow -> next = fast;
        fast -> next = st;
        slow = st;
        fast =ft;
    }
}

Sort List

LeetCode/力扣

  • 归并排序
ListNode* merge(ListNode* p1, ListNode* p2) {
    ListNode* t, *head = p1;
    while(p2 && p1) {
        if(p1 -> val > p2 -> val) {
            int temp = p1 -> val;
            p1 -> val = p2 -> val;
            p2 -> val = temp;

            t = p2 -> next;
            p2 -> next = p1 -> next;
            p1 -> next = p2;
            p2 = t;
            p1 = p1 -> next;
        } else {
            p1 = p1 -> next;
        }
    }
    if(!p1 && p2) {
        t = head;
        while(t ->next) t = t -> next;
        t -> next =p2;
    }
    return head;
}

ListNode* sort(ListNode* head) {
    if(head -> next == nullptr) return head;
    ListNode *slow = head, *fast = head;
    while(fast -> next != nullptr && fast -> next -> next != nullptr) {
        slow = slow -> next;
        fast = fast -> next -> next;
    }
    ListNode* head2 = slow -> next;
    slow -> next = nullptr;
    sort(head);
    sort(head2);
    return merge(head, head2);
}
ListNode* sortList(ListNode* head) {
    if(head == nullptr) return head;
    return sort(head);
}

Remove Linked List Elements

LeetCode/力扣

  • 删除前后,链表不要断
ListNode* removeElements(ListNode* head, int val) {
    ListNode *prev = head;
    while(prev != nullptr && prev -> val == val) {
        prev = prev -> next;
    }
    head = prev;
    if(head == nullptr) return head;
    ListNode* next = prev -> next;
    while(next != nullptr) {
        if(next -> val == val) {
            prev -> next = next -> next;
            next -> next -> next;
            continue;
        }
        prev = prev -> next;
        next = next -> next;
    }
    return head;
}

Palindrome Linked List

LeetCode/力扣

  • 递归, 递归到最后,相当于首尾逐个比较
int ans = 1;
ListNode *root;
void helper(ListNode *head) {
    if(head == nullptr) return;
    helper(head->next);
    if(head -> val  != root -> val) ans = 0;
    root = root -> next;
}

bool isPalindrome(ListNode* head) {
    if(head == nullptr || head -> next == nullptr) return true;
    root =head;
    helper(head);
    return ans == 1;
}
  • 快慢指针找到后面的链表
  • 然后翻转后半部分
  • 再逐一比较
ListNode *reverse(ListNode *head) {
    ListNode prev = nullptr;
    while(head) {
        ListNode* next = head-> next;
        head -> next = prev;
        prev = head;
        head = next;
    }
    return prev;
}

bool isPalindrome(ListNode *head) {
    if(!head) return true;

    ListNode *slow = head, *fast = head;

    while(fast && fast -> next && fast -> next -> next) {
        fast = fast -> next -> next;
        slow = slow -> next;
    }
    fast = slow -> next;
    slow -> next  = nullptr;
    for(ListNode *left = head, *right = reverse(fast); left && right; left = left -> next, right = right -> next) {
        if(left -> val != right -> val) return false;
    }
    slow -> next = fast;
    return true;
}

Middle of the Linked List

LeetCode/力扣

  • 快慢指针直接解决
ListNode *middleNode(ListNode *head) {
    if(head == nullptr) return head;
    ListNode *prev = head, *next = head;
    while(next != nullptr && next -> next != nullptr) {
        prev = prev -> next;
        next = next -> next -> next;
    }
    return prev;
}

标签:快慢,head,slow,ListNode,nullptr,fast,next,LeetCode,指针
来源: https://www.cnblogs.com/xnzone/p/16435640.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有