分割链表

编写程序以 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;
 *     struct ListNode *next;
 * };
 */
struct ListNode *partition(struct ListNode *head, int x)

方法1

用两个链表来分别放大的和小的

typedef struct ListNode *List;
typedef struct ListNode Node;
struct ListNode *partition(struct ListNode *head, int x)
{
    if (!head || !head->next)
    {
        return head;
    }
//头节点,没有头结点你不会记得它的位置的
    List small = (List)malloc(sizeof(Node));
    List big = (List)malloc(sizeof(Node));
//两个记录的指针,让他们后移
    List Srecord = small;
    List Brecord = big;
//先初始
    small->next = NULL;
    big->next = NULL;
    
    while (head)
    {
        if (head->val < x)
        {
            Srecord->next = head;//指针指向head,然后移到head
            Srecord = head;
        }
        else
        {
            Brecord->next = head;
            Brecord = head;
        }
        head = head->next;
    }
    Brecord->next = NULL;//最后一个置空
    Srecord->next = big->next;//接上
    return small->next;
}

方法二

头插法

头插法,你首先要有一个头,然后每次发现的小的你就把它看插到后面。

在这里插入图片描述
有点像小时候站队,小的站前面,我们这里规定比x小的站x前面,比x大的站x后面。而Head就是第一排的那条线,线上不站人,一个一个向后数,从哪里数呢?从第二个人也就是later开始数,为什么不是before,因为如果发现小的,我们就放到before前面就可以了,比如later开始后面都比x小,那自然所有人都到了before前面。而这里我们也不需要关注,比x大的和比x小的怎么排。

  • 那从later开始,比x小的就放before前面,而Head是不变的,我们做四件事。
    在这里插入图片描述
  1. 将later后面的用before记住,因为later要插到前面,就找不到后面了
  2. 我这里的箭头指的是Head的后面而不是before,因为可能before前面已经有了小值,如果这样指向before前面的就会丢掉,也就不叫头插法了。在这里插入图片描述
  3. 头插法就是插到头结点的后面,later放到Head后
  4. 将later后移一位,做下一次比较,正好是我们before指向的。

用c语言翻译就是

 before->next = later->next;
 later->next = Head->next;
 Head->next = later;
 later = before->next;

对于上面说的4,也可以再用一个指针指向later->next,但是要记得将before接上。

k = later->next;
later->next = Head->next;
Head->next = later;
later = k;
before->next = k;

在这里插入图片描述

  • 那比later大呢?
    我们就把later与before向后移就是了。
before = later;
later = later->next;
struct ListNode *partition(struct ListNode *head, int x)
{
    if (!head || !head->next)
        return head;
    struct ListNode *Head = (struct ListNode*)malloc(sizeof(struct ListNode));//头结点,没有有效数据
    Head->next = head;
    struct ListNode *before = head;
    struct ListNode *later = head->next;
    while(later)
    {
        if (later->val <x)
        {
            before->next = later->next;
            later->next = Head->next;
            Head->next = later;
            later = before->next;
        }
        else
        {
            before = later;
            later = later->next;
        }
    }
    return Head->next;
}

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-list-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

©️2020 CSDN 皮肤主题: 1024 设计师: 上身试试 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值