合并两个有序列表

本来很简单一题,很久没写算法题了居然在细节上纠结了我好久,唉~
这种简单题就应该用简单的思路来做…在这也提醒各位,有的题真的只是看起来容易,真的写起来又会有好多乱七八糟的问题了。

闲话少说,上题吧,这是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;
    }
};

好嘛,我觉得代码写的还是挺菜的…
在这里插入图片描述

原文地址:https://www.cnblogs.com/yinyoupoet/p/13287448.html