21.合并两个有序链表
leetcode21
解题思路:
解法1,递归
时间复杂度为O(M+N);空间复杂度为O(m+n);
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l1 == nullptr) {
return l2;
} else if (l2 == nullptr) {
return l1;
} else if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
};
解法2,迭代,设置亚结点后,逐一对比,将较小的接在后面
时间复杂度O(M+N);空间复杂度为O(1);
/**
* 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) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1==nullptr||l2==nullptr) return l1?l1:l2;
ListNode *dummpy=new ListNode(-1);
ListNode *cur=dummpy;
while(l1!=nullptr&&l2!=nullptr){
if(l1->val>l2->val){
cur->next=l2;
l2 = l2->next;
}else{
cur->next=l1;
l1=l1->next;
}
cur=cur->next;
}
cur->next=l1?l1:l2;
return dummpy->next;
}
};
22.括号生成
leetcode22
解题思路:
最开始考虑的也是利用回溯的思想,但是没考虑到左括号先加,当右括号数量小于左括号时添加右括号这一点。
class Solution {
public:
vector<string>res;
string str="";
void dfs(int n,int open,int close){
if(str.size()==2*n){
res.push_back(str);
return;
}
//首先加入左括号,列举出所有的可能
if(open<n){
str.push_back('(');
dfs(n,open+1,close);
str.pop_back();//回溯,这个位置也可能是右括号
}
//当右括号数量小于左括号时,加入右括号
if(close<open){
str.push_back(')');
dfs(n,open,close+1);
str.pop_back();
}
}
vector<string> generateParenthesis(int n) {
if(n==0) return res;
dfs(n,0,0);
return res;
}
};
23.合并K个升序链表
解题思路
解法1:利用前面21题的合并两个有序链表,用循环两两合并即可;
时间复杂度为n+2*n+…+i*n=k2n; 空间复杂度为O(1)
/**
* 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) {}
* };
*/
class Solution {
public:
ListNode * mergetwo(ListNode *p1,ListNode *p2){
if(p1==nullptr||p2==nullptr) return p1==nullptr?p2:p1;
ListNode *head=new ListNode(INT_MIN);
ListNode *pre=head;
while(p1!=nullptr&&p2!=nullptr){
if(p1->val>=p2->val){
pre->next=p2;
p2=p2->next;
}else{
pre->next=p1;
p1=p1->next;
}
pre=pre->next;
}
pre->next=(p1==nullptr)?p2:p1;
return head->next;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode *ans=nullptr;
for(int i=0;i<lists.size();i++){
ans=mergetwo(ans,lists[i]);
}
return ans;
}
};
解法2:分治合并
/**
* 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) {}
* };
*/
class Solution {
public:
ListNode * mergetwo(ListNode *p1,ListNode *p2){
if(p1==nullptr||p2==nullptr) return p1==nullptr?p2:p1;
ListNode *head=new ListNode(INT_MIN);
ListNode *pre=head;
while(p1!=nullptr&&p2!=nullptr){
if(p1->val>=p2->val){
pre->next=p2;
p2=p2->next;
}else{
pre->next=p1;
p1=p1->next;
}
pre=pre->next;
}
pre->next=(p1==nullptr)?p2:p1;
return head->next;
}
ListNode* merge_sort(vector<ListNode*>&lists,int left,int right){
if(left==right) return lists[left];
if(left>right){
return nullptr;
}
int mid=left+((right-left)>>1);
ListNode*l1=merge_sort(lists,left,mid);
ListNode*l2=merge_sort(lists,mid+1,right);
return mergetwo(l1,l2);
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.size()==0) return nullptr;
return merge_sort(lists,0,lists.size()-1);
}
};