归并排序类题目
介绍
说是归并排序类的题目其实就是合并过程这个部分的思想:两个序列(链表、数组或者字符串等),合并成为一个序列的问题。
问题描述
问题分析
题目意思很明显了,两个链表合并。有一个需要注意的点:两个要合并链表的第一个节点判断数值大小之后用什么接着:虚拟头节点。
代码表述
/**
* 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*node=new ListNode(-1);//建立虚拟头节点
auto res=node;//要返回的节点
//归并排序的思想了
while(l1&&l2){
if(l1->val<=l2->val){
node->next=l1;
l1=l1->next;//不要忘记了更新链表节点
}
else{
node->next=l2;
l2=l2->next;
}
node=node->next;
}
if(l1)node->next=l1;
else if(l2)node->next=l2;
return res->next;
}
};
复杂度分析
时间复杂度:O(两个链表的长度)。需要遍历两个链表。
空间复杂度:O(1).两个节点的额外空间。
问题描述
问题分析
同理,合并排序的思路。但是这里A数组可以充当辅助数组的作用。
代码表述
class Solution {
public:
void merge(vector<int>& A, int m, vector<int>& B, int n) {
//双指针,从后面开始
//A中的末尾有足够空间,所以可以先设定A的大小为A+B的大小,然后双指针比较AB两个集合中的元素大小,大的放在最末尾即可
//注意可能有一方的元素提前取完,之后将剩下的直接放入数组即可
int l=m;
int r=n;
while(l&&r){
if(A[l-1]>=B[r-1]){//注意数组下标
A[l+r-1]=A[l-1];
l--;
}
else {
A[l+r-1]=B[r-1];
r--;
}
}
if(l==0){
while(r){
A[r-1]=B[r-1];
r--;
}
}
}
};
复杂度分析
时间复杂度:O(两个数组的长度)。需要遍历两个链表。
空间复杂度:O(1)直接使用A的空间,没有使用额外空间。
问题描述
问题分析
思路也挺简单,对代码处理要熟悉。
代码表述
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 计算两个数之和
* @param s string字符串 表示第一个整数
* @param t string字符串 表示第二个整数
* @return string字符串
*/
// int re(int sum){
// if(sum>=10)return 1;
// else if(sum<10)return 0;
// }
string solve(string s, string t) {
// write code here
//二合一,感觉好多都是归并和插入排序的思路,排序牛逼
int sum=0;//数字个位上的和
int flag=0;//进位标志,进位表示1
s='0'+s;//避免边界条件,如果最终第一个字符不是0,说明进位了
t='0'+t;
int i=s.size()-1;
int j=t.size()-1;
string str;
while(i>=0&&j>=0){//循环截止条件都是细节
sum=s[i]-'0'+t[j]-'0'+flag;
//大于10就进一
if(sum>=10){
flag=1;
}
else if(sum<10){
flag=0;
}
str+=to_string(sum%10);
i--;
j--;
}
//可能一个数字已经算完了
while(i>=0){
sum=s[i]-'0'+flag;
if(sum>=10)flag=1;
else if(sum<10)flag=0;
str+=to_string(sum%10);
i--;
}
while(j>=0){
sum=t[j]-'0'+flag;
if(sum>=10)flag=1;
else if(sum<10)flag=0;
str+=to_string(sum%10);
j--;
}
//别忘了反转
reverse(str.begin(), str.end());
//如果第一个还是‘0’,那就两个首位就没有进1
if(str[0]=='0')return str.substr(1);
return str;
}
};
复杂度分析
时间复杂度:O(两个字符序列的长度)。需要遍历两个字符序列。
空间复杂度:O(1)。