题目链接
题目描述
为什么可以用递归
- 递归 = 人脑 + 计算机递归结构
- 递归是人脑借助计算机递归结构去解决问题
- 人脑发现问题具有递归结构,于是借助计算机递归结构去解决问题
- 所以递归算法脱离计算机之后根本不存在
- 我们采用递归算法把问题解出来,仅仅只是借助了计算机的递归结构,完全是计算机的功劳
- 对于递归来说,计算机为我们承担了暴力计算的全部。人脑在此时的价值仅仅体现在把问题交给计算机而已
- 对于递归算法来说人脑的价值不体现在:帮助计算机更轻松的计算,减轻计算机负担;也不体现在:脱离计算机,在完全靠人脑的情况下,通过更聪明的方式让人脑解决问题。
- 也就是说递归算法几乎配不上算法这两个字,所谓递归算法的全部内容仅仅只是:发现这个问题具有递归结构,正好借用计算机递归计算,交给计算机去计算。仅此而已
解法1:递归法
class Solution {
public:
ListNode* dfs(ListNode* list1, ListNode* list2)
{
if (list1 == nullptr) return list2;
if (list2 == nullptr) return list1;
if (list1->val <= list2->val)
{
list1->next = dfs(list1->next, list2);
return list1;
}
list2->next = dfs(list2->next, list1);
return list2;
}
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* object_head = dfs(list1, list2);
return object_head;
}
};
递归分析
大家可以先阅读一下:leetcode:面试题 08.06. 汉诺塔问题-CSDN博客
本问题与汉诺塔问题有何不同呢?
- 汉诺塔问题的递归主逻辑中可是没有if语句做条件判断的
- 本问题根据条件判断语句,依照实际情况有选择的去做递归
- 汉诺塔问题中不需要分情况去有选择的递归
- 如果本问题不是采用有选择的递归,将会非常复杂。
解法2:利用容器multimap
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
if (list1 == nullptr && list2 == nullptr) {
return nullptr;
}
multimap<int, ListNode*> myMultimap;
while (list1)
{
myMultimap.insert(make_pair(list1->val, list1));
list1 = list1->next;
}
while (list2)
{
myMultimap.insert(make_pair(list2->val, list2));
list2 = list2->next;
}
ListNode* tmp;
auto it = myMultimap.begin();
if (it != myMultimap.end()) {
tmp = it->second;
}
int count = 1;
for (const auto& pair : myMultimap)
{
if (count > 1)
{
tmp->next = pair.second;
tmp = pair.second;
}
count++;
}
tmp->next = nullptr;
return myMultimap.begin()->second;
}
};
解法2分析
- 该题是为了排序,且有重复元素,正好利用multimap的特性
- 时间复杂度是O(nlogn),递归法时间复杂度是O(n)