链表的题目总是让我很惆怅。
动辄就会runtime error。
比如这题,额外用了一个节点的空间来保存头节点。我很不情愿多用这个空间,不过貌似不行。(貌似不行,实际可行,见附录。把头节点提出循环)
实现类:
class Solution {
public:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
ListNode *root,*p;
if(l1==NULL) return l2;
if(l2==NULL) return l1;
p = new ListNode(0);
root=p;
while(l1!=NULL && l2!=NULL){
if(l1->val < l2->val) {
p->next=l1;
p=l1;
l1=l1->next;
//p->next=NULL;
}
else{
p->next=l2;
p=l2;
l2=l2->next;
//p->next=NULL;
}
}
if(l1!=NULL)
p->next=l1;
if(l2!=NULL){
p->next=l2;
return root->next;
}
};
测试类:
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode *reverse(ListNode *root){
ListNode *p=NULL,*tmp;
while(root!=NULL){
tmp=root->next;
root->next=p;
p=root;
root=tmp;
}
return p;
}
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
ListNode *root,*p;
if(l1==NULL) return l2;
if(l2==NULL) return l1;
p = new ListNode(0);
//root=l1->val > l2->val ? l2:l1;//cout<<root->val<<endl;
root=p;
while(l1!=NULL && l2!=NULL){
if(l1->val < l2->val) {
p->next=l1;
p=l1;
l1=l1->next;
//p->next=NULL;
}
else{
p->next=l2;
p=l2;
l2=l2->next;
//p->next=NULL;
}
}
if(l1!=NULL){
p->next=l1;
if(l2!=NULL){
p->next=l2;
return root->next;
}
int main() {
// your code goes here
int num;
ListNode *p,*q;
ListNode *root=NULL;
int m,n;cin>>m>>n;
while(m--){cin>>num;
p=new ListNode(num);
p->next=root;
root=p;
}//cout<<endl;
root=reverse(root);
while(n--){cin>>num;
p=new ListNode(num);
p->next=q;
q=p;
}//cout<<endl;
q=reverse(q);
p=mergeTwoLists(root,q);
while(p!=NULL) {cout<<p->val<<" ";p=p->next;}
return 0;
}
因为是按头插法构建链表的,所以构建完时要reverse一下。不喜尾插法,要多用一个空间,且看这别扭。附录:(简洁且无dummy head)
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
if(NULL == l1) return l2;
if(NULL == l2) return l1;
ListNode* head=NULL; // head of the list to return
// find first element (can use dummy node to put this part inside of the loop)
if(l1->val < l2->val) { head = l1; l1 = l1->next; }
else { head = l2; l2 = l2->next; }
ListNode* p = head; // pointer to form new list
// I use && to remove extra IF from the loop
while(l1 && l2){
if(l1->val < l2->val) { p->next = l1; l1 = l1->next; }
else { p->next = l2; l2 = l2->next; }
p=p->next;
}
// add the rest of the tail, done!
if(l1) p->next=l1;
else p->next=l2;
return head;
}