合并两个有序列表
本来很简单一题,很久没写算法题了居然在细节上纠结了我好久,唉~
这种简单题就应该用简单的思路来做…在这也提醒各位,有的题真的只是看起来容易,真的写起来又会有好多乱七八糟的问题了。
闲话少说,上题吧,这是leetcode的第21题,各位可以去网站上面刷刷,经过那个测试才知道你的代码会不会有你没发现的问题。
分析:
首先,题目所给的函数如下,返回是一个指针,如果我在函数内部动态malloc
一个链表,那么必然导致在出了函数之后那块地址被释放了,所以返回值只能从输入的参数下手。我这里选择的是l1
,即将l2
中的元素依次插入l1
中。
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {}
再来看题目,很显然输入的是一个不带头结点的单链表,这用起来就很麻烦,毕竟我里面要频繁地进行插入操作,而插入操作要求对链表的->next
节点进行操作,因为每当l2指向的元素比l1指向的元素小时,我要把l2指向的元素插入到l1所指的元素的前面的,如果不带头结点那就操作起来太麻烦了,因此我们可以自己定义头结点,我的程序里为head1和head2
有头结点还不行,要考虑一个情况:
l1: [2]
l2: [1]
按照上面的思路,l2已经能够全部正常插入了,但是这种情况下,l1指针要如何保持指向第一个元素呢?因此我在代码里添加了如下代码:
if(head1->next->next == l1) l1 = head1->next;
最后要考虑l1为空的问题,如果l1为空那么直接返回l2就好了。
以下为我的代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(!l1) return l2;
ListNode* head1 = (ListNode*)malloc(sizeof(ListNode));
ListNode* head2 = (ListNode*)malloc(sizeof(ListNode));
head1->next = l1;
head2->next = l2;
while(head1->next && head2->next)
{
if(head1->next->val > head2->next->val)
{
ListNode* temp2 = head2->next->next;
head2->next->next = head1->next;
head1->next = head2->next;
head2->next = temp2;
if(head1->next->next == l1) l1 = head1->next;
}
head1 = head1->next;
}
if(head2->next)
{
while(head1->next) head1=head1->next;
head1->next = head2->next;
}
return l1;
}
};
好嘛,我觉得代码写的还是挺菜的…