1.移除元素
1.1 力扣连接
https://leetcode-cn.com/problems/remove-element/https://leetcode-cn.com/problems/remove-element/
1.2 题目内容
给你一个数组
nums
和一个值val
,你需要 原地 移除所有数值等于val
的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用
O(1)
额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
输入:nums = [3,2,2,3], val = 3 输出:2, nums = [2,2] 解释:函数应该返回新的长度 2 , 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
1.3 解题方法
双指针法
1. 数组头尾各放一个指针
2. 如果头指针所指元素不是 val 则向后移动,相同则和尾指针所在位置互换元素,两个指针相向移动。
3. 减少nizeSize
4. 指针相遇停止。
// 需要考虑只有一个元素 ,尾指针是否一开始的位置是否不等于 val?
int removeElement(int* nums, int numsSize, int val)
{
int *ps=nums;
int *pe=nums+numsSize-1;
while(ps<=pe)
{
if(numsSize==1)
{
if(*nums==val)
return 0 ;
else
return 1;
}
//判断尾部指针是否指向非val元素
if(*ps==val && *pe!=val)
{
int num = 0;
num=*ps;
*ps=*pe;
*pe=num;
}
//不指向的话向前移动一步
if(*pe==val)
pe--;
//判断头部指针是否指向val元素
if(*ps!=val)
ps++;
}
return pe-nums+1;
}
2. 删除有序数组中的重复项
2.1 力扣连接
2.2 题目内容
给你一个 非严格递增排列 的数组
nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回nums
中唯一元素的个数。考虑
nums
的唯一元素的数量为k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。- 返回
k
。示例 1:
输入:nums = [1,1,2] 输出:2, nums = [1,2,_] 解释:函数应该返回新的长度 2,并且原数组 nums 的前两个元素被修改为 1, 2 不需要考虑数组中超出新长度后面的元素。
2.2 解题方法
双指针法
非严格递增排列 的数组:后一项比前一项大或相等。
1. 头指针记录储存位置。
2. 尾指针判断是否比头指针大,大的话存在头指针下一个位置。
3. 头指针向后移动一位。
//注意尾指针的移动范围不超过数组大小。
int removeDuplicates(int* nums, int numsSize)
{
int *ps=nums;
int *pe=nums+1;
//判断*pe是否比*ps大,pe是否超出数组范围
while(ps<=pe && pe<=nums+numsSize-1)
{
if(*pe!=*ps)
*(++ps)=*pe;
pe++;
}
return ps-nums+1;
}
3. 合并两个有序数组
3.1 力扣连接
3.2 题目内容
给你两个按 非递减顺序 排列的整数数组
nums1
和nums2
,另有两个整数m
和n
,分别表示nums1
和nums2
中的元素数目。请你 合并
nums2
到nums1
中,使合并后的数组同样按 非递减顺序 排列。注意:最终,合并后数组不应由函数返回,而是存储在数组
nums1
中。为了应对这种情况,nums1
的初始长度为m + n
,其中前m
个元素表示应合并的元素,后n
个元素为0
,应忽略。nums2
的长度为n
。示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 输出:[1,2,2,3,5,6] 解释:需要合并 [1,2,3] 和 [2,5,6] 。 合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
3.3 解题方法
双指针法
1. 新建一个数组装合并后形成的新的数组
2. 比较分别在两个数组上建立一个指针相互比较数字大小小的或者等于放入新数组中。
//注意两个数组长短问题?
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{
int arr[500] = { 0 };
int* a = arr;
int* ps = nums1;
int* pe = nums2;
while (ps <= nums1 + m - 1 && pe <= nums2 + n - 1)
{
if (*ps < *pe)
*a++ = *ps++;
else if (*ps > *pe)
*a++ = *pe++;
else
{
*a++ = *pe++;
*a++ = *ps++;
}
}
while (ps <= nums1 + m - 1 || pe <= nums2 + n - 1)
{
if (ps <= nums1 + m - 1)
*a++ = *ps++;
else if (pe <= nums2 + n - 1)
*a++ = *pe++;
}
for (int i = 0; i < n + m; i++)
{
nums1[i] = arr[i];
}
}