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)
}
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