题目: 给定一个链表的头节点和一个特定值 x ,请你对链表进行分隔,使得所有小于 x 的节点都出现在大于等于 x 的节点之前 ( 链表中节点数为[0,500],不要求链表的顺序 )
思路一:在原链表上进行修改
在原链表进行修改,若 pcur 节点的值小于 x ,往后走;若 pcur 节点的值大于或等于 x ,为插在原链表后,删除旧节点
思路二: 创建新链表
若 pcur 节点的值小于 x, 头插在新链表中;若 pcur 节点的值大于或等于 x, 尾插在新链表中
思路三: 创建新链表 小链表和大链表
对于每一个链表,只需要尾插即可,思路更为清淅
typedef struct ListNode ListNode;
ListNode* mergeTwoLists(ListNode* head, int x)
{if (head == NULL){return head; }//创建两个带头链表ListNode* lesshead, *lesstail;ListNode* greaterhead, *greatertail;lessHead = (ListNode*)malloc(sizeof(ListNode));greaterhead = (ListNode*)malloc(sizeof(ListNode));//遍历原链表,将原链表中的节点尾插到大小链表中ListNode* pcur = head;while (pcur){if (pcur->next < x){lesstail->next = pcur;pcur = pcur->next; } else{greatertail->next = pcur;pcur = pcur->next; }}lesstail->next = greaterhead->next;ListNode* ret = lessehad->next;free(Lesshead);free(geaterhead);lesshead = greaterhead = NULL;return ret;
}
当我们运行这段代码,会发现超出时间限制,也就是发生了死循环。重新审视代码,我们发现,虽然我们处理了小链表的尾节点,但是大链表的尾节点我们一直没有处理。回到我们示例的情况,大链表的最后一个节点是 5,但是它对于原来的链表,它的 next 指向的是 2 , 所以在将两个链表相连的时候 5 又指回了 2,链表中出现一个小环,在打印链表时会陷入死循环,这就是导致问题的地方。
最后只需加一句:
lesstail->next = greaterhead->next;
//修改大链表的尾节点的next指针指向
greatertail->next = NULL; //若不加这一句,代码会死循环ListNode* ret = lessehad->next;
还没完
再次运行代码,依然超时
假设原链表只有一个节点 1 , x = 2,此时我们看回代码,1 这个节点会进入小链表,但是,由于我们创建的两个哨兵位是没有设置初始值的,所以 greaterhead->next 其实是指向随机的地址,我们无法得知是哪个地址所以程序报错。
只需将这两段代码调换位置,即先对哨兵位设置初始值即可解决问题。
我们直接看修改后的完整代码(标注了调换的位置)
typedef struct ListNode ListNode;
ListNode* mergeTwoLists(ListNode* head, int x)
{if (head == NULL){return head; }//创建两个带头链表ListNode* lesshead, *lesstail;ListNode* greaterhead, *greatertail;lessHead = (ListNode*)malloc(sizeof(ListNode));greaterhead = (ListNode*)malloc(sizeof(ListNode));//遍历原链表,将原链表中的节点尾插到大小链表中ListNode* pcur = head;while (pcur){if (pcur->next < x){lesstail->next = pcur;pcur = pcur->next; } else{greatertail->next = pcur;pcur = pcur->next; }}//调换位置后//修改大链表的尾节点的next指针指向greatertail->next = NULL; //若不加这一句,代码会死循环lesstail->next = greaterhead->next;ListNode* ret = lessehad->next;free(Lesshead);free(geaterhead);lesshead = greaterhead = NULL;return ret;
}