标题:现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针(C语言实现)
这道题的难度是较难,但是思想却很简单,我们把小于 x 的放在一个链表中,大于 x 的放在一个链表中,然后再将这两个链表合并。
我们假设 x 的值是 10,将小于 x 的结点放在 lessHead( lessHead 是头结点) 和 lessTail 后面,然后把 cur 更新成 lessTail (方便下次尾插找尾),同理, 大于 x 的结点也是, 最后在更新 cur
class Partition {
public:
ListNode* partition(ListNode* pHead, int x)
{
struct ListNode* lessHead,*lessTail,*greaterHead,*greaterTail;
lessHead = lessTail = (struct ListNode*)malloc(sizeof(struct ListNode));
greaterHead = greaterTail = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* cur = pHead;
while(cur)
{
if(cur->val < x)
{
lessTail->next = cur;
lessTail = cur;
}
else
{
greaterTail->next = cur;
greaterTail = cur;
}
//更新cur
cur = cur->next;
}
//将两个链表链接在一起
lessTail->next = greaterHead->next;
struct ListNode* head = lessHead->next;
free(lessHead);
free(greaterHead);
return head;
}
};
提示 : 牛客网这道题并没有C语言的模板,直接选择 C++ 就可以了。
但是上面的代码在牛客网上是过不去的:
并且测试用例和错误提示也让人很迷茫, 这时我们就要考虑边界情况,链表的边界一般都是头结点和尾结点, 我们来换一组这样的数据分析一下:
问题就出现在这里,我们把 greaterTail->next赋值成 NUL L就可以了
class Partition {
public:
ListNode* partition(ListNode* pHead, int x)
{
struct ListNode* lessHead,*lessTail,*greaterHead,*greaterTail;
lessHead = lessTail = (struct ListNode*)malloc(sizeof(struct ListNode));
greaterHead = greaterTail = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* cur = pHead;
while(cur)
{
if(cur->val < x)
{
lessTail->next = cur;
lessTail = cur;
}
else
{
greaterTail->next = cur;
greaterTail = cur;
}
//更新cur
cur = cur->next;
}
greaterTail->next = NULL;
//将两个链表链接在一起
lessTail->next = greaterHead->next;
struct ListNode* head = lessHead->next;
free(lessHead);
free(greaterHead);
return head;
}
};