今天遇到了leetcode的一道需要使用到归并排序的问题,然后开始自己学一下归并排序,写一下总结
就不说一些废话了,先了解一点,整个归并排序用到的就是递归的思想,所以在这边说一下那句话
递归就是一个遍历的思想,说实在,现在还不是太明白递归,等慢慢搞明白了,再写一下总结吧
void mysort(vector<int>&nums){
vector<int> temp = vector<int>(nums.size());
//在这边定义一个数组,就可以避免在递归里面去重复定义了
mysort(nums,0,nums.size()-1,temp);
}
在C++这边,定义了两个mysort(),为了避免我们在递归里面去重复第建立数组,所以我们这边先进行定义,并且去调用我们实际上的mysort,也就是第二个mysort(),如下
void mysort(vector<int>&nums,int left ,int right,vector<int>&temp){
if(left >=right){
return ;
}else {
int mid = (left+right)/2;
mysort(nums,left,mid,temp);//遍历我们左半边的数组
mysort(nums,mid+1,right,temp);//遍历我们右半边的数组
mymerge(nums,left,mid,right,temp);
}
}
代码是不是特别简单呢?嘿嘿,我们只需要递归的思想,利用二分法,将数组分成两半,一直往下分,分出一个个的单体,然后再把这些单体合并起来,就可以获得我们最终的结果。
引用自https://www.cnblogs.com/chengxiao/p/6194356.html
所以我们的merge函数就是再进行下面的那个合并的步骤,也就是在进行我们的回溯
void mymerge(vector<int>&nums,int left,int mid,int right,vector<int> temp){
int i = left;
int j = mid+1;
int t =0;
while(i<=mid&&j<=right){
if(nums[i]<=nums[j]){
temp[t++] = nums[i++];//这边的话,对于这个t++,嘿嘿,挺好玩的
}else{
temp[t++] = nums[j++];//这个也是
}
}
while(i<=mid){
temp[t++] = nums[i++];
}
while(j<=right){
temp[t++] = nums[j++];
}
t = 0;
//将temp中的元素全部拷贝到原数组中
while(left <= right){
nums[left++] = temp[t++];
}
}
上面的代码就是合并两个有序的数组,就这个简单,所以归并排序特别的简单,嘿嘿,好好加油💪,问我为什么写得这么简单,因为我不知道怎么讲了,递归这东西,深入进去不好理解,随缘吧,先当个笔记,以后回来填坑。
完整的代码如下
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
void mymerge(vector<int>&nums,int left,int mid,int right,vector<int> temp){
int i = left;
int j = mid+1;
int t =0;
while(i<=mid&&j<=right){
if(nums[i]<=nums[j]){
temp[t++] = nums[i++];
}else{
temp[t++] = nums[j++];
}
}
while(i<=mid){
temp[t++] = nums[i++];
}
while(j<=right){
temp[t++] = nums[j++];
}
t = 0;
//将temp中的元素全部拷贝到原数组中
while(left <= right){
nums[left++] = temp[t++];
}
}
void mysort(vector<int>&nums,int left ,int right,vector<int>&temp){
if(left >=right){
return ;
}else {
int mid = (left+right)/2;
mysort(nums,left,mid,temp);
mysort(nums,mid+1,right,temp);
mymerge(nums,left,mid,right,temp);
}
}
void mysort(vector<int>&nums){
vector<int> temp = vector<int>(nums.size());
mysort(nums,0,nums.size()-1,temp);
}
int main(){
vector<int > number ={1,3,2,3,1,5,7,8,4};
mysort(number);
for(const auto x:number){
cout<<x<<" ";
}
return 0;
}
附上Leetcode的题目链接
翻转对
以及题解
void reversePairs(vector<int>&nums,int left,int right,vector<int>&temp,int &ans){
if(left==right){
return;
}else{
int mid = (left+right)/2;
reversePairs(nums,left,mid,temp,ans);
reversePairs(nums,mid+1,right,temp,ans);
//统计下标对的数量
int i = left;
int j = mid+1;
while(i<=mid){
while (j<=right&&(long long)nums[i]>2*(long long)nums[j]) j++;
ans+=(j-mid-1);
i++;
}
i = left;
j = mid+1;
int t =0;
while(i<=mid&&j<=right){
if(nums[i]<nums[j]){
temp[t++] = nums[i++];
}else{
temp[t++] = nums[j++];
}
}
while(i<=mid){
temp[t++] =nums[i++];
}
while(j<=right){
temp[t++] = nums[j++];
}
t=0;
while(left<=right){
nums[left++] = temp[t++];
}
}
}
void reversePairs(vector<int>& nums) {
vector<int> temp = vector<int>(nums.size());
int ans=0;
reversePairs(nums,0,nums.size()-1,temp,ans);
cout<<ans;
}
主要逻辑代码
//统计下标对的数量
int i = left;
int j = mid+1;
while(i<=mid){
while (j<=right&&(long long)nums[i]>2*(long long)nums[j]) j++;
ans+=(j-mid-1);
i++;
}
这边的内容是判断合并之前的有序数组的符合翻转的组数,就只有这个代码,所以递归的本质就是遍历
***
递归就是遍历