面试题 02.04. 分割链表

编写程序以 x 为基准分割链表,使得所有小于 x 的节点排在大于或等于 x 的节点之前。如果链表中包含 x,x 只需出现在小于 x 的元素之后(如下所示)。分割元素 x 只需处于“右半部分”即可,其不需要被置于左右两部分之间。

示例:

输入: head = 3->5->8->5->10->2->1, x = 5
输出: 3->1->2->10->5->5->8

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    //删除某个节点比返回该节点指针
    ListNode* del(ListNode* node,ListNode* pre){
        if(node != nullptr){
            pre->next = node->next;
            node->next = nullptr;
        }
        return node;
    }
    //头插、尾差、双指针三种方法都实现
    ListNode* partition(ListNode* head, int x) {
        //3 5 8 10 2 1   5
        ListNode* dummy = new ListNode(-1);
        dummy->next = head;
        ListNode* pre = dummy;
        while(head){
            if(head->val >= x){
                pre = head;
                head = head->next;
            }else{
                ListNode* node = del(head,pre);
                head = pre->next;
                node->next = dummy->next;
                dummy->next = node;
                if(pre == dummy) pre = pre->next;
            }  
        }
        return dummy->next;
    }
};

//尾插法:注意几点,到之前的end就要结束了,不能等到了end,因为end一直在后移动

//end后移注意  end = node。指end指向新的node

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* del(ListNode* node,ListNode* pre){
        if(node){
            pre->next = node->next;
            node->next = nullptr;
        }
        return node;
    }
    //尾插法,顺序与之前一致
    ListNode* partition(ListNode* head, int x) {
        //3 5 8 5 10 2 1   
        //可以先找到尾部
        ListNode* hTmp = head;
        ListNode* end = head;
        while(head){
            end = head;
            head = head->next;
        }
        ListNode* dummy =  new ListNode(-1);
        dummy->next = hTmp;
        ListNode* pre = dummy;
        //到end之前.这里容易出bug,end回后移
        ListNode* PreEnd = end;
        while(hTmp != PreEnd){
            if(hTmp->val < x){
                pre = hTmp;
                hTmp = hTmp->next;
            }else{
                ListNode* node = del(hTmp,pre);
                hTmp = pre->next;
                end->next = node;
                end = node;
            }
        }
        return dummy->next;
    }
};

//双指针法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* del(ListNode* node,ListNode* pre){
        if(node != nullptr){
            pre->next = node->next;
            node->next = nullptr;
        }
        return node;
    }
    //双指针法:前指针指向小yu X的最后一个节点
    //后指针为当前指针,>= X的话就继续后移
    ListNode* partition(ListNode* head, int x) {
        ListNode* pre = new ListNode(-1);
        pre->next = head;
        ListNode* cur = head;
        ListNode* PreCur = pre;
        ListNode* dummy = pre;
        // 3 5 8 5 2 1      5
        while(cur){
            if(cur->val < x){
                ListNode* node = del(cur,PreCur);
                //cur移动
                cur = PreCur->next;
                //插入node
                node->next = pre->next;
                pre->next = node;
                pre = node;
                if(PreCur->next != cur){
                    PreCur = pre;
                }
            }else{
                PreCur = cur;
                cur = cur->next;
            }
        }
        return dummy->next;
    }
};

  

原文地址:https://www.cnblogs.com/wsw-seu/p/13381672.html