您的位置:首页 > 其它

LeetCode :: Merge Two Sorted Lists 详细分析

2014-03-25 16:56 459 查看
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first
two lists.

合并两个排好序的链表,这里重新设置两个指针,l3、trail,一个指示新链表的头结点,另一个指示新链表的最末有效结点。这道题目也基本不涉及什么可以展开探讨的知识点,但是可以一步步精简代码,下面附上我从一开始写的非常丑的代码,一直到精简后的代码的过程。

/**
 * 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) {
            ListNode *l3 = NULL, *trail;
            if (!l1 && !l2)
                return NULL;
            if (!l1)
                return l2;
            if (!l2)
                return l1;
            if (l1 -> val <= l2 -> val){
                l3 = l1;
                l1 = l1 -> next;
            }
            else{
                l3 = l2;
                l2 = l2 -> next;
            }		//判断l1 和 l2中小的一个头结点为新链表头结点。
trail = l3;
            while (l1 && l2){
                if (l1 -> val <= l2 ->val){
                    trail -> next = l1;
                    l1 = l1 -> next;
                    trail = trail -> next;
                }
                else{
                    trail -> next = l2;
                    l2 = l2 -> next;
                    trail =trail -> next;
                }
            }
            while (l1){
                trail -> next = l1;
                l1 = l1 -> next;
                trail = trail -> next;
            }
            while (l2){
                trail -> next = l2;
                l2 = l2 -> next;
                trail =trail -> next;
            }
            return l3;
    }
};
第一次写完一次AC,但是这个代码写的真的太丑了,然后最后两个while循环明显是不必要的,只要把余下的一支链表直接接上就可以了。

class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
            ListNode *l3 = NULL, *trail;
            if (!l1 && !l2)
                return NULL;
            if (!l1)
                return l2;
            if (!l2)
                return l1;
            if (l1 -> val <= l2 -> val){
                l3 = l1;
                l1 = l1 -> next;
            }
            else{
                l3 = l2;
                l2 = l2 -> next;
            }
            trail = l3;
            while (l1 && l2){
                if (l1 -> val <= l2 ->val){
                    trail -> next = l1;
                    l1 = l1 -> next;
                    trail = trail -> next;
                }
                else{
                    trail -> next = l2;
                    l2 = l2 -> next;
                    trail =trail -> next;
                }
            }
            if (l1)
                trail -> next = l1;
            else
                trail -> next = l2;
            return l3;
    }
};


反复审视了一下,觉得还是有冗余的地方,然后决定大改一下代码。这里引入一个哑结点(dummy)(这里也参考其他人的博文)。这里哑节点的引入的好处,可以看到不用再对头结点进行特殊的判断,而是将头结点和其后的结点一视同仁,这也是为什么在 《数据结构与算法分析》一书中,作者很推崇引入哑结点的原因了。

*/
class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        ListNode dummy(-1);
        ListNode* prev = &dummy;
        while(l1 != NULL && l2 != NULL)
        {
            ListNode* tmp;
            if(l1->val < l2->val) tmp = l1, l1 = l1->next;
            else tmp = l2, l2 = l2->next;
            prev->next = tmp;
            prev = prev->next;
        }
        if(l1 == NULL && l2 == NULL) prev->next = NULL;
        if(l1 != NULL) prev->next = l1;
        if(l2 != NULL) prev->next = l2;
        
        return dummy.next;
    }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: