21-合并两个有序链表

题目:

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

解答:

解答一:思想与三数之和一样,还是双指针

/**
* Definition for singly-linked list.*/
 struct ListNode {
     int val;
     ListNode *next;
     ListNode() : val(0), next(nullptr) {}
     ListNode(int x) : val(x), next(nullptr) {}
     ListNode(int x, ListNode *next) : val(x), next(next) {}
};

ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) 
{
    if (l1 == nullptr)
        return l2;
    if (l2 == nullptr)
        return l1;

    ListNode* result = new ListNode();
    ListNode* tmp = result;
    while (true)
    {
        if (l1 == nullptr && l2 == nullptr)
            break;
        if (l1 == nullptr)
        {
            tmp->val = l2->val;
            l2 = l2->next;

            if (l2 != nullptr)
            {
                tmp->next = new ListNode();
                tmp = tmp->next;
            }
            
            continue;
        }
        if (l2 == nullptr)
        {
            tmp->val = l1->val;
            l1 = l1->next;

            if (l1 != nullptr)
            {
                tmp->next = new ListNode();
                tmp = tmp->next;
            }
            
            continue;
        }

        if (l1->val < l2->val)
        {
            tmp->val = l1->val;
            l1 = l1->next;
            tmp->next = new ListNode();
            tmp = tmp->next;
        }
        else
        {
            tmp->val = l2->val;
            l2 = l2->next;
            tmp->next = new ListNode();
            tmp = tmp->next;
        }
    }

    return result;
}

问题:代码里new的太多了,影响速度跟内存,查看解答后代码修改如下:

解答二:

ListNode* mergeTwoLists2(ListNode* l1, ListNode* l2)
{
    if (l1 == nullptr)
        return l2;
    if (l2 == nullptr)
        return l1;
    ListNode* result = new ListNode(-1);
    ListNode* tmp = result;

    while (l1 != nullptr && l2 != nullptr)
    {
        if (l1->val < l2->val)
        {
            tmp->next = l1;
            l1 = l1->next;
        }
        else
        {
            tmp->next = l2;
            l2 = l2->next;
        }
        tmp = tmp->next;
    }

    //while结束后,还有一个队尾的元素没有加入
    if (l1 == nullptr)
        tmp->next = l2;
    if (l2 == nullptr)
        tmp->next = l1;

    return result->next;
}

分析:该方法中,结果的next每次都指向已经存在的一个节点,因此不用new,而且注意返回的结果是result->next而不是result,所有代码中只在构造result时new了一次,代码优于第一个解法。

 

posted @ 2020-11-14 10:38  adfas  阅读(89)  评论(0编辑  收藏  举报