力扣刷题之面试题 02.04.分割链表

题目描述

也就是把结点值小于x的,放在左边,大于等于的放在右边

解题思路

每次定义新节点太麻烦了,我们先typedef一下给链表名:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
   
  
     
}

我的思路是这样的,创建两个新链表,一个是小链表,一个是大链表:

让一个pcur指针遍历原链表,如果找到节点值比x小的,那么就尾插到小链表中,否则就尾插到大链表中,然后把小链表和大链表连接起来。

这里的小链表和大链表都设置成带头链表简化思路,避免空指针多考虑空链表的情况。

解题步骤

首先先定义pcur和两个新链表:


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
   
   ListNode*lesshead,*lesstail;
   ListNode*greathead,*greattail;
   lesshead=lesstail=(ListNode*)malloc(sizeof(ListNode));
   greathead=greattail=(ListNode*)malloc(sizeof(ListNode));
 ListNode*pcur=head;

    
}

然后根据刚刚的思路我们进行两个大小链表的尾插

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
   
   if(head==NULL)
   {
    return head;
   }
   ListNode*lesshead,*lesstail;
   ListNode*greathead,*greattail;
   lesshead=lesstail=(ListNode*)malloc(sizeof(ListNode));
   greathead=greattail=(ListNode*)malloc(sizeof(ListNode));
 ListNode*pcur=head;
 while(pcur)
 {
    if(pcur->val<x)
    {
         lesstail->next=pcur;
         lesstail=lesstail->next;
    }
    else
    {
        greattail->next=pcur;
        greattail=greattail->next;
    }
    pcur=pcur->next;
 }
   

}

然后我们将两个链表连接起来:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
   
   ListNode*lesshead,*lesstail;
   ListNode*greathead,*greattail;
   lesshead=lesstail=(ListNode*)malloc(sizeof(ListNode));
   greathead=greattail=(ListNode*)malloc(sizeof(ListNode));
 ListNode*pcur=head;
 while(pcur)
 {
    if(pcur->val<x)
    {
         lesstail->next=pcur;
         lesstail=lesstail->next;
    }
    else
    {
        greattail->next=pcur;
        greattail=greattail->next;
    }
    pcur=pcur->next;
 }
//连接
     lesstail->next=greathead->next;
     
     return ret;
}

我们的理想效果是这样的,那然后把lesshead>next指针return回去是不是就好了?

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
   
   if(head==NULL)
   {
    return head;
   }
   ListNode*lesshead,*lesstail;
   ListNode*greathead,*greattail;
   lesshead=lesstail=(ListNode*)malloc(sizeof(ListNode));
   greathead=greattail=(ListNode*)malloc(sizeof(ListNode));
 ListNode*pcur=head;
 while(pcur)
 {
    if(pcur->val<x)
    {
         lesstail->next=pcur;
         lesstail=lesstail->next;
    }
    else
    {
        greattail->next=pcur;
        greattail=greattail->next;
    }
    pcur=pcur->next;
 }
     lesstail->next=greathead->next;
   
     return lesshead->next;
}

运行之后超出时间限制,一般就是是出现了死循环,这是为什么呢?

我们就写了一个循环,而且pcur一直在走,是一定会走到NULL的位置,可是为什么还是会出现死循环?

原因在于

我们的链表是一个一个节点相连的

大链表的尾插情况是不是这样的?其实不是而是这样的:

5和2这两个节点是连着的,把5拿下来的同时,2也跟在后面,那么连接大小链表的同时就变成了这样:

变成了循环链表,自然就变成了死循环,那么我们把greattail->next指针置为NULL,即可

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
   
   ListNode*lesshead,*lesstail;
   ListNode*greathead,*greattail;
   lesshead=lesstail=(ListNode*)malloc(sizeof(ListNode));
   greathead=greattail=(ListNode*)malloc(sizeof(ListNode));
 ListNode*pcur=head;
 while(pcur)
 {
    if(pcur->val<x)
    {
         lesstail->next=pcur;
         lesstail=lesstail->next;
    }
    else
    {
        greattail->next=pcur;
        greattail=greattail->next;
    }
    pcur=pcur->next;
 }
     greattail->next=NULL;
     lesstail->next=greathead->next;

   
     return lesshead->next;
}

再来跑一下代码:

两个测试用例都跑过了,那么我们提交一下:

提交通过,但是有一点,因为链表本身为空的情况也跑过了,

greattail->next=NULL;
     lesstail->next=greathead->next;
 
     return lesshead->next;

如果head本身就是空链表,我们传空链表回去就行,我们这里没有传空链表的语句,但是提交可以跑过是因为上述代码,当链表为空时,pcur没有进去循环,那么大小链表我们本身也没有初始化next指向NULL而是在这里加了一句让大小链表断开循环的语句,所以代码才误打误撞跑过,,而且我们申请了两块链表空间,没有释放,尽管力扣会帮我们释放,但是为了让代码健壮性更好,养成好习惯我们手动释放,且把相应的指针置为NULL,并把原链表head为NULL的情况,再添加一条语句,下面是修改后的完整解题代码:

完整代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
   
   if(head==NULL)
   {
    return head;
   }
   ListNode*lesshead,*lesstail;
   ListNode*greathead,*greattail;
   lesshead=lesstail=(ListNode*)malloc(sizeof(ListNode));
   greathead=greattail=(ListNode*)malloc(sizeof(ListNode));
 ListNode*pcur=head;
 while(pcur)
 {
    if(pcur->val<x)
    {
         lesstail->next=pcur;
         lesstail=lesstail->next;
    }
    else
    {
        greattail->next=pcur;
        greattail=greattail->next;
    }
    pcur=pcur->next;
 }
     lesstail->next=greathead->next;
     ListNode*ret=lesshead->next;
     free(lesshead);
     free(greathead);
     lesstail=greattail=NULL;
     lesshead=greathead=NULL;
     return ret;
}

感谢浏览。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值