Leetcode——面试题02.04.分割链表

面试题 02.04. 分割链表 - 力扣(LeetCode) 

对于该链表OJ,我们两种大的方向:

1.在原链表上修改;2.创建新链表,遍历原链表。

在原链上进行修改:如果该节点的val小于x则继续往后走,如果大于等于x则将该节点尾插到该链表,然后删除该节点,继续遍历;

创建新链表,遍历原链表:对于这种方式也有两种

  • 创建一个新链表,遍历原链表,如果节点的val小于x则头插到新链表中,如果大于等于x则尾插到新链表中。
  • 创建两个新链表:little和big。遍历原链表,如果节点的val值小于x则尾插到little链表中,如果节点的val值大于等于x则尾插到big链表中,遍历完后,连接这两个新链表即可。

我们今天来实现创建两个新链表的方式来解决问题。

我们在创建链表的时候可以采取带头链表的方式,这样可以避免重复代码的出现。 

新链表前的红色圆点就代表着头节点也叫做哨兵位。 我们创建完链表并遍历完之后,就得到了两个大小链表,我们只需要将这两个连接起来就可以了。

我们通过上面代码连接好之后 ,就得到了如图的链表,那么是否可以直接返回little->next?

答案是不行!!! 在该链表中出现了循环结构,程序会陷入死循环。那么怎么解决这个问题呢?

该问题出现的原因是因为big链表的尾节点的next指针指向的不是NULL造成的。我们只需要在连接之前将big链表的尾节点的next指针指向NULL就行了。

 下面附上完整代码(注:该代码是leetcode的解题代码,不包括main函数)

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x)
{
    //已知链表为空,直接返回NULL
    if(head == NULL)
    {
        return NULL;
    }
    //已知链表不为空
    //创建两个新链表,为了避免重复代码,可以利用哨兵位
    ListNode* little = (ListNode*)malloc(sizeof(ListNode));
    ListNode* littletail = little;
    ListNode* big = (ListNode*)malloc(sizeof(ListNode));
    ListNode* bigtail = big;
    //遍历原链表
    while(head)
    {
        if(head->val<x)
        {
            //小于x,将节点尾插little中
            littletail->next = head;
            littletail = littletail->next;
        }
        else
        {
            //大于等于x,将该节点尾插到big中
            bigtail->next = head;
            bigtail = bigtail->next;
        }
        //遍历下一个节点
        head = head->next;
    }
    //退出循环说明已经遍历完了原链表
    //修改bigtail指向,否则会陷入死循环
    bigtail->next = NULL;

    //连接大小链表
    //因为这两个链表都是带头链表,所以连接时要指向头结点的下一个节点
    littletail->next = big->next;
    
    return little->next;
}

完!

  • 22
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值