双指针法-删除数组中的重复元素以及奇偶排序
程序员文章站
2022-07-14 07:54:05
...
双指针法-删除数组中的重复元素以及奇偶排序
1.1双指针法简介——原地排序
双指针法,即一个快指针和一个慢指针,快指针提前遍历数组元素,慢指针停在被处理元素位置。可以用数组的索引实现双指针算法。
1.2删除数组中的重复元素
1.2.1解题思路
给定数组是有序的(若无序,首先调用排序,当然输出的元素也是有序的),那么重复的元素一定会相邻。要求删除重复元素,实际上就是将不重复的元素移到数组的左侧,最后返回不重复元素的个数即可。为慢指针,为快指针,可以理解为数组的索引。
1.比较 和 位置的元素是否相等。
(1)如果相等, 后移 1 位, 保持不动。
(2)如果不相等,将位置的元素复制到 位置上, 后移一位, 后移 1 位
2.重复上述过程,直到 等于数组长度。
返回 ,即为新数组长度。
1.2.2实现代码(C++)
int removeDuplicates(vector<int>& nums)
{
int p = 0;
for (int q = 1; q < nums.size(); q++)
{
if (nums[p] != nums[q])
{
nums[++p] = nums[q];
}
}
return ++j;
}
若用C语言实现,将数组的定义形式改变和传入数组长度即可。
复杂度分析
时间复杂度:,假设数组的长度是 ,那么 和 分别最多遍历 步。
空间复杂度:。
1.3奇偶排序
1.3.1问题描述
给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素在最左边,所有奇数元素在最右。
例如
输入:
输出:
输出也会被接受。
1.3.2解题思路
从上述的删除数组的重复元素可以看出,指针均在数组最前面,对于奇偶排序,则是将放在数组最前面,指针放在数组最后面,采用对2取余判断出奇偶数。
在指针移动的过程中两个指针取余的结果记为,则有如下四种情况:
如果是 (0, 1),那么万事大吉 i++ 并且 j–。
如果是 (1, 0),那么交换两个元素,然后继续。
如果是 (0, 0),那么说明 i 位置是正确的,只能 i++。
如果是 (1, 1),那么说明 j 位置是正确的,只能 j–。
1.3.3实现代码
vector<int> sortArrayByParity(vector<int>& A)
{
int i = 0;
int j = A.size() - 1;
int temp;
while (i < j)
{
if ((A[i] % 2) > (A[j] % 2))
{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
if (A[i] % 2 == 0)
{
i++;
}
if (A[j] % 2 == 1)
{
j--;
}
}
return A;
}