题集-链表分割

链表分割_牛客题霸_牛客网 (nowcoder.com)

题集-链表分割_第1张图片

 

链表去做的话,可以分为带哨兵位和不带哨兵位两种,但是不带哨兵位会更麻烦一些,更容易出现空指针问题。

这里两种思路都是:将小于x的结点尾插到less链表中,将大于x的结点尾插到greater链表中,最终再将lesstail指向greaterhead

不带哨兵位:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/

#include 

class Partition {
  public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        if(pHead == NULL) return NULL;//空链表返回空
        if(pHead -> next == NULL) return pHead;
        ListNode* lesshead = NULL, * lesstail = NULL;
        ListNode* greaterhead = NULL, * greatertail = NULL;
        ListNode* cur = pHead, *next = pHead -> next;
        while (cur)
         {
            if(cur->val < x) 
            {
                if (lesstail == NULL) 
                {
                    cur -> next = NULL;
                    lesshead = lesstail = cur;
                } 
                else 
                {
                    cur -> next = NULL;
                    lesstail -> next = cur;
                    lesstail = cur;
                }
            } 
            else 
            {
                    if (greatertail == NULL)
                     {
                        cur -> next = NULL;
                        greaterhead = greatertail = cur;
                    }
                     else {
                        cur -> next = NULL;
                        greatertail -> next = cur;
                        greatertail = cur;
                    }
            }
                cur = next;
                if(cur) //如果不判断的话,最后cur走到最后一个结点的时候,next产生空指针问题。
                next = cur -> next;
            }

        if(lesshead == NULL) return greaterhead;//如果第一个链表为空,则直接返回第二个链表头指针
        lesstail -> next = greaterhead;
        return lesshead;
        }
};

带哨兵位的就相对简单一些:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/

#include 

class Partition {
  public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        if(pHead == NULL) return NULL;
        if(pHead -> next == NULL) return pHead;
        ListNode * lesshead = (ListNode*)malloc(sizeof(ListNode));
        lesshead -> next = NULL;
        ListNode * greaterhead = (ListNode*)malloc(sizeof(ListNode));
        greaterhead -> next = NULL;
        ListNode * lesstail = lesshead, * greatertail = greaterhead,*cur = pHead,*next = cur->next;

        while(cur)
        {
             if(cur -> val < x)
             {
                cur -> next = NULL;
                lesstail -> next = cur;
                lesstail = cur;
             }
             else 
             {
                cur -> next = NULL;
                greatertail -> next = cur;
                greatertail = cur;
             }
             cur = next;
             if(cur)
             next = cur -> next;
        }

        lesstail -> next = greaterhead -> next;
       //把两个链表拼在一起的时候需要去掉第二个链表的头结点
        free(greaterhead);
        return lesshead->next;
       //返回的时候不能返回头结点的地址,因为头结点不存任何数据,所以要返回头结点指向的那个结点的地址。

        }
};

其中,还有一些需要规避的小问题,注释里都写到了。

分享一个小技巧:

因为做oj类的题目时,链表问题调试起来就会有些麻烦,还要用头插尾插方式进行构建链表样例

但是其实不用,一般这类题目放到我们的vs中的话,我们可以快速构建链表:

ListNode* a = (ListNode*)malloc(sizeof(ListNode));
    assert(a);
    ListNode* b = (ListNode*)malloc(sizeof(ListNode));
    assert(b);
    ListNode* c = (ListNode*)malloc(sizeof(ListNode));
    assert(c);
    ListNode* d = (ListNode*)malloc(sizeof(ListNode));
    assert(d);
    a->val = 0;
    b->val = 7;
    c->val = 2;
    d->val = 0;
    a->next = b;
    b->next = c;
    c->next = d;
    d->next = NULL;
    ListNode* plist = a;

SLPrint(partition(plist, 5));

这样就可以随心构建链表,然后进行调试。

你可能感兴趣的:(链表,数据结构)