【leetcode】86 partition list

题目说明

https://leetcode-cn.com/problems/partition-list/description/
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。

解法1

遍历链表,记录最后一个小于x的结点less,当遍历到的结点小于x时,将该点插入到less之后,直到遍历结束。

/*
 * 时间复杂度:O(n)
 * 记录最后一低点小于x的点less
 * 遍历链表,当遍历到的点(pre)的下一个点(cur)小于x时,将下一点(cur)插入到less之后,less相应向后移动一位
 * 并且pre需要指向原cur的下一个点(next),保证链表不会断,所以要以pre来遍历
 * 特殊情况:当满足条件时,当less与当前点前一点重合时,只需要向后移动一位即可
 */
ListNode* partition(ListNode* head, int x) {
    if (head == NULL)
        return NULL;
    ListNode *dummy = new ListNode(0);
    dummy->next = head;

    ListNode *pre = dummy;
    ListNode *less = dummy;
    ListNode *cur = NULL;
    ListNode *cur_next = NULL;

    while(pre->next){
        cur = pre->next;
        if (cur->val < x){
            if (pre == less){
                less = less->next;
                pre = pre->next;
                continue;
            }
            cur_next = cur->next;//记录当前点下一个结点
            cur->next = less->next;//当前点指向less的下一个结点
            less->next = cur;//less指向当前点,即完成插入操作
            pre->next = cur_next;//前一点指向所记录的原当前点下一个结点,保持链表完整性
            less = less->next;//less后移,pre不需要后移,因为其next已经变化了
        } else
            pre = pre->next;
    }
    return dummy->next;
}

解法2

添加两个链表,分别记录小于x的结点与大于等于x的结点,遍历链表时,将对应的结点插入到链表中,最后将两个链表拼接到一起。

/*
 * 时间复杂度:O(n)
 * 添加两个链表
 * 小于x的记录到一个链表
 * 其他大于等于的记录到另一外链表
 * 然后两个链表拼接
 * 注意:最后一个结点需要指向NULL
 */
ListNode* partition2(ListNode* head, int x) {
    ListNode *lessNode = new ListNode(0);
    ListNode *moreNode = new ListNode(0);

    ListNode *lessCur = lessNode;
    ListNode *moreCur = moreNode;

    ListNode *cur = head;
    while(cur){
        if (cur->val < x){
            lessCur->next = cur;
            lessCur = lessCur->next;
        }else{
            moreCur->next = cur;
            moreCur = moreCur->next;
        }
        cur = cur->next;
    }

    lessCur->next = moreNode->next;
    moreCur->next = NULL;
    return lessNode->next;
}

猜你喜欢

转载自www.cnblogs.com/JesseTsou/p/9569942.html