• 86.Partition List


    给定一个链表,以及一个整数 target,将链表上小于这个target的节点移到大于等于target 的前面。


    Input: head = 1->4->3->2->5->2, x = 3
    Output: 1->2->2->4->3->5


    思路:
    用2个指针,slow和fast,slow指向小于大于等于target的前一个节点,即slow指向的是当前小于target的最后一个节点,移动fast,找到剩余节点中fast->next比target小的节点,然后将其移到slow的下一个节点,更新slow, fast 即可。为什么是比较slow->next / fast->next,而不是slow / fast,需要想明白节点的交换,需要前一个节点的指针,就算你找到当前节点是需要交换的节点,但你的前一个节点没有,就无法更新链表

    难点:
    1.如果头结点大于等于target,也就是说头结点就需要交换,解决办法就是,在头结点前面放置一个我们自己申请的节点
    2.交换后fast的下一个节点改变了,此时不应该更新fast = fast->next,而是应该继续判断,新的fast->next 是否还需要交换。此处有点像75题的思路。
    3.因为都是在判断slow->next, fast->next ,所以当slow/fast = NULL时,空指针->next就会报错,注意处理为空指针的情况。

    class Solution {
    public:
        ListNode* partition(ListNode* head, int x) {
            if (!head || !head->next) return head;
            ListNode* res = new ListNode(-1), * slow = res, * fast = head;
            res->next = head;
            while (slow->next) { //首先找到需要在slow节点后面开始插入的地方
                if (slow->next->val >= x) break;
                slow = slow->next;
            }
            fast = slow->next;//在slow后面开始找fast
            if (!fast) return res->next;//空指针判断
            while (fast->next) {
                if (fast->next->val < x) {
                    ListNode* tmpSlowNext = slow->next;
                    ListNode* tmpFastNext = fast->next;
                    fast->next = tmpFastNext->next;
                    slow->next = tmpFastNext;
                    tmpFastNext->next = tmpSlowNext;
                    slow = slow->next;
                    continue;//此时应该继续判断新的fast->next是否继续需要交换
                }
                fast = fast->next;
            }
            return res->next;
        }
    };

    稍微修改版:

    class Solution {
    public:
        ListNode* partition(ListNode* head, int x) {
            if (!head || !head->next) return head;
            ListNode* res = new ListNode(-1), * slow = res, * fast = head;
            res->next = head;
            while (slow->next) { //首先找到需要在slow节点后面开始插入的地方
                if (slow->next->val >= x) break;
                slow = slow->next;
            }
            fast = slow;//slow是一定非空,所以将 fast = slow,减少一次空指针判断
            while (fast->next) {
                if (fast->next->val < x) {
                    ListNode* tmpSlowNext = slow->next;
                    ListNode* tmpFastNext = fast->next;
                    fast->next = tmpFastNext->next;
                    slow->next = tmpFastNext;
                    tmpFastNext->next = tmpSlowNext;
                    slow = slow->next;
                }
                else fast = fast->next;
            }
            return res->next;
        }
    };
  • 相关阅读:
    ubuntu 16.04常见错误--Could not get lock /var/lib/dpkg/lock解决
    Ubuntu 16.04 LTS安装搜狗拼音输入法网易云音乐 Remarkable
    Ubuntu 16.04 LTS(入门一)国内快速更新软件源
    C语言程序注释风格
    【译】基于主机的卡仿真(Host-based Card Emulation)
    NFC Spy:基于Android 4.4及以上手机的非接智能卡跟踪仪
    Ubuntu 16.04 Vim安装及配置
    Alpha阶段 第九次Scrum Meeting
    Alpha阶段 第八次Scrum Meeting
    Alpha阶段 第七次Scrum Meeting
  • 原文地址:https://www.cnblogs.com/luo-c/p/13036629.html
Copyright © 2020-2023  润新知