1. 题⽬链接:912.排序数组
2. 题⽬描述:
3. 解法(归并排序):
算法思路:
归并排序的流程充分的体现了「分⽽治之」的思想,⼤体过程分为两步:
◦ 分:将数组⼀分为⼆为两部分,⼀直分解到数组的⻓度为1 ,使整个数组的排序过程被分为 「左半部分排序」+「右半部分排序」;
◦ 治:将两个较短的「有序数组合并成⼀个⻓的有序数组」,⼀直合并到最初的⻓度。
C++算法代码:
class Solution
{
public:
vector<int>temp; //临时数组
void mergesort(vector<int>& nums,int l,int r)
{
//当只剩一个元素时停止划分
if(l>=r)
{
return;
}
//数组划分
//取中间值
int mid=(r+l)/2;
mergesort(nums,l,mid);
mergesort(nums,mid+1,r);
//归并
int cur1=l,cur2=mid+1,i=0;
while(cur1<=mid&&cur2<=r)
{
temp[i++]=nums[cur1]<nums[cur2]?nums[cur1++]:nums[cur2++];
}
//处理没有遍历完的部分
while(cur1<=mid)
{
temp[i++]=nums[cur1++];
}
while(cur2<=r)
{
temp[i++]=nums[cur2++];
}
//修改原数组
for(int i=l;i<=r;i++)
{
nums[i]=temp[i-l];
}
}
vector<int> sortArray(vector<int>& nums)
{
//开空间
temp.resize(nums.size());
mergesort(nums,0,nums.size()-1);
return nums;
}
};
Java算法代码:
class Solution
{
int[] tmp;
public int[] sortArray(int[] nums)
{
tmp = new int[nums.length];
mergeSort(nums, 0, nums.length - 1);
return nums;
}
public void mergeSort(int[] nums, int left, int right)
{
if (left >= right) return;
// 1. 根据中间点划分区间
int mid = (left + right) / 2;
// [left, mid] [mid + 1, right]
// 2. 先把左右区间排个序
mergeSort(nums, left, mid);
mergeSort(nums, mid + 1, right);
// 3. 合并两个有序数组
int cur1 = left, cur2 = mid + 1, i = 0;
while (cur1 <= mid && cur2 <= right)
tmp[i++] = nums[cur1] <= nums[cur2] ? nums[cur1++] : nums[cur2++];
// 处理没有遍历完的数组
while (cur1 <= mid) tmp[i++] = nums[cur1++];
while (cur2 <= right) tmp[i++] = nums[cur2++];
// 4. 还原
for (int j = left; j <= right; j++)
nums[j] = tmp[j - left];
}
}