21. Merge Two Sorted Lists 和 148. Sort List

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.

Example:

Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4

重写一道easy题,刚才第一次竟然没写出来。coding能力实在太差。AC代码:

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

同时在答案中发现了一个coding很优雅的回答,也贴在这里:

class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        ListNode dummy(INT_MIN);
        ListNode *tail = &dummy;
        
        while (l1 && l2) {
            if (l1->val < l2->val) {
                tail->next = l1;
                l1 = l1->next;
            } else {
                tail->next = l2;
                l2 = l2->next;
            }
            tail = tail->next;
        }

        tail->next = l1 ? l1 : l2;
        return dummy.next;
    }
};

这个回答在开始和结束的处理上比我要优雅很多。

开头:没有判断到底l1和l2哪个大,而是引入了一个虚假的头节点,把第一次的比较大小也放入后面的主循环中。

结束:在l1或者l2穷尽之后直接把尾指针指向非空的哪个就好,不需要一个一个复制了。


Sort a linked list in O(n log n) time using constant space complexity.

拿到这道题之后回顾对数组排序的所有算法,其中O(nlgn)的只有快速排序和归并排序。这里写一个归并排序的方法:

先回顾常规的归并排序:

sort(){

sort(left)

sort(right)

merge(left,right)

}

这里面如果left和right都是链表,我们其实是会做的(就是上一题,融合两个有序链表)。所以唯一需要做的修改就是把left和right两个链表的形式改成和上一题一样(尾节点的next为null),这道题同样调了好久,主要还是coding能力太弱了。在看了别人的解答,了解思路的情况下,主要体现在递归用的不熟悉。
循环边界调节处理的很草率,没有用实际例子测试而是想当然(coding习惯问题)

divide and conquer 解决思路:

1. 把问题抽象成模块,写出模块之间的联系.

divide and conquer编程范式为

divide --> conquer --> combine

比如说这道题就是,每一个sort函数都有如下步骤:

divide(left, right)

sort(left) sort(right)

merge(left,right)

2. 设定边界条件:循环函数退出的条件

head == null || head->next == null


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值