个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创分治算法(1)_颜色分类
收录于专栏【经典算法练习】
本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌
目录
1. 分治思想简介 :
2. 题目链接 :
3. 题目描述 :
4. 解法(三指针) :
题目分析 :
算法思路 :
代码展示 :
结果分析 :
1. 分治思想简介 :
分治思想(Divide and Conquer)是一种广泛应用于算法设计中的重要策略,其基本思想是将一个复杂的问题分解为多个较简单的子问题,递归地解决这些子问题,然后将它们的解合并为原问题的解。(分而治之)
分治思想在很多经典算法中得到了应用,以下是几个常见的例子:
1. 归并排序(Merge Sort):将数组分为两个部分,分别进行排序,然后合并两个已排序的部分。
2. 快速排序(Quick Sort):选择一个“基准”元素,将数组划分为比基准小和大的两部分,递归排序这两部分。
3. 二分查找(Binary Search):在有序数组中查找一个元素,通过不断地将搜索范围减半来达到快速查找的目的。
4. 矩阵乘法(Strassen’s Algorithm):通过分解矩阵为子矩阵来减少乘法的复杂度。
5. 快速傅里叶变换(FFT):在信号处理和图像处理中用于高效地计算离散傅里叶变换。
分治法的优点:
效率:通过将问题规模减小到较小的子问题,能够在较短的时间内求解复杂问题。
清晰性:分治法的递归结构使得算法逻辑更加清晰和易于理解。
适应性:许多问题可以自然地用分治法来解决,从而减少编程的复杂性。
2. 题目链接 :
OJ链接 : 颜色分类
3. 题目描述 :
给定一个包含红色、白色和蓝色、共 n
个元素的数组 nums
,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0
、 1
和 2
分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
示例 1:
输入:nums = [2,0,2,1,1,0] 输出:[0,0,1,1,2,2]
示例 2:
输入:nums = [2,0,1] 输出:[0,1,2]
提示:
n == nums.length
1 <= n <= 300
nums[i]
为0
、1
或2
4. 解法(三指针) :
题目分析 :
题目要求: 给定一个包含红色、白色和蓝色、共 n个元素的组数组 nums ,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。(使用整数 0、 1 和 2 分别表示红色、白色和蓝色。)
所以这个我们只能对原数组进行排序,不能额外创建空间,更不能直接使用库里面的sort(虽然能通过~~):
class Solution {
public:
void sortColors(vector<int>& nums) {
sort(nums.begin(), nums.end());
}
};
算法思路 :
类比数组分块的算法思想,这里是将数组分成三块,我们可以再添加一个指针,实现数组分为三块.
设数组大小为n,定义三个指针left, cur, right:
left: 用来标记0序列的末尾,因此初始化为-1;
cur: 用来扫描数组,初始化为0;
right: 用来标记2序列的起始未知,因此初始化为n
在cur往后扫描的过程中,保证:
[0, left]内的元素都是0
[left + 1, cur - 1]内的元素都是1
[cur, right -1] 内的元素是待定元素
[right, n]内的元素都是2
所以我们在扫描的过程中有:
1. nums[cur] == 0 : swap(nums[++left], nums[cur++])
2. nums[cur] == 1 : cur++
3. nums[cur] == 2 : swap(nums[--right], nums[cur]) 注意这里cur不需要++,因为[cur, right - 1]是待定元素,还需要判断!
代码展示 :
class Solution {
public:
void sortColors(vector<int>& nums) {
int left = -1, right = nums.size(), cur = 0;
while(cur < right)
{
if(nums[cur] == 0) swap(nums[++left], nums[cur++]);
else if(nums[cur] == 2) swap(nums[--right], nums[cur]);
else cur++;
}
}
};
结果分析 :
时间复杂度分析:
O(n),其中 n 是数组 nums 的长度。每个元素最多处理一次。
空间复杂度分析:
使用的额外空间:该算法只使用了常量级别的额外空间,主要是 left、right 和 cur 三个指针,没有使用额外的数组或数据结构。因此,空间复杂度为:O(1),只使用了常数级的空间。