题目
1.移除元素
题目链接:27. 移除元素 - 力扣(LeetCode)
https://leetcode.cn/problems/remove-element/
题目描述
给你一个数组
nums和一个值val,你需要 原地 移除所有数值等于val的元素。元素的顺序可能发生改变。然后返回nums中与val不同的元素的数量。假设
nums中不等于val的元素数量为k,要通过此题,您需要执行以下操作:
更改
nums数组,使nums的前k个元素包含不等于val的元素。nums的其余元素和nums的大小并不重要。返回
k。
思路一:普通法
创建一个与nums一样的新数组,然后遍历数组nums,将不等于val的值都存入新数组中,最后再用nums替换新数组即可。
代码实现:
int removeElement(int* nums, int numsSize, int val) {
int* newnums = (int*)malloc(numsSize * sizeof(int)); // 分配内存
if (newnums == NULL)
return 0;
int k=0;
for(int i=0;i<numsSize;i++)
{
if(nums[i]!=val)
{
newnums[k]=nums[i];
k++;
}
}
for(int i=0;i<k;i++)
{
nums[i]=newnums[i];
}
free(newnums);
return k;
}
思路二:双指针法
使用双指针法,一个指针src在前面探路,另一个指针dst在后面站岗,图解如下

代码实现:
int removeElement(int* nums, int numsSize, int val) {
int src=0,dst=0;
while(src<numsSize)
{
if(nums[src]!=val)
{
nums[dst]=nums[src];
dst++;
}
src++;
}
return dst;
}
2.删除有序数组中的重复项
题目描述
给你一个 非严格递增排列 的数组
nums,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回nums中唯一元素的个数。考虑
nums的唯一元素的数量为k。去重后,返回唯一元素的数量k。
nums的前k个元素应包含 排序后 的唯一数字。下标k - 1之后的剩余元素可以忽略。
这道题和上一道题有些相似,但是有些地方思路也大有不同。
思路一:普通法
创建一个与nums一样的新数组,用两个变量来对比数组nums,然后遍历寻找不一样的元素,将不重复出现的值都存入新数组中,最后再用nums替换新数组即可。
代码实现:
int removeDuplicates(int* nums, int numsSize) {
int i=0,j=0;
int k=0;
int* newnums=(int*)malloc(numsSize*sizeof(int));
if(newnums==NULL)
{
return 0;
}
newnums[k++]=nums[j++];
while(j<numsSize)
{
if(nums[i]!=nums[j])
{
newnums[k++]=nums[j];
}
i++;
j++;
}
for(int n=0;n<k;n++)
{
nums[n]=newnums[n];
}
return k;
}
这样写下来确实要比思路二“双指针法”麻烦一点,而且也违背了 “原地” 这一规则。
思路二:双指针法
双指针法,图解如下

代码实现:
int removeDuplicates(int* nums, int numsSize) {
int dst=0,src=dst+1;
while(src<numsSize)
{
if(nums[dst]!=nums[src] && ++dst!=src)//src和dst指向同一个值时不用赋值
{
nums[dst]=nums[src];
}
src++;
}
return dst+1;
}
3.合并两个有序数组
题目链接:88. 合并两个有序数组 - 力扣(LeetCode)
https://leetcode.cn/problems/merge-sorted-array/description/
题目描述
给你两个按 非递减顺序 排列的整数数组
nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目。请你 合并
nums2到nums1中,使合并后的数组同样按 非递减顺序 排列。注意:最终,合并后数组不应由函数返回,而是存储在数组
nums1中。为了应对这种情况,nums1的初始长度为m + n,其中前m个元素表示应合并的元素,后n个元素为0,应忽略。nums2的长度为n。
思路一:普通法
先合并数组,然后再对合并后的数组排序即可。
代码实现:
int cmp(const void* p1,const void* p2)
{
return (*(int *)p1-*(int *)p2);
}
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
int j=0;
for(int i=m;i<nums1Size;i++)
{
nums1[i]=nums2[j];
j++;
}
qsort(nums1,nums1Size,sizeof(nums1[0]),cmp);
}
思路二:三指针法
用三个变量定位,从后往前遍历两个数组,找大,谁大谁往后放。图解如下:

代码实现:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
int l1=m-1;
int l2=n-1;
int l3=m+n-1;
while(l1>=0 && l2>=0)
{
if(nums1[l1]>nums2[l2])
{
nums1[l3--]=nums1[l1--];
}
else
{
nums1[l3--]=nums2[l2--];
}
}
while(l2>=0)
{
nums1[l3--]=nums2[l2--];
}
}
以上就是我分享的顺序表部分的练习题目了,如果大家有更好的题目欢迎在评论区分享!

被折叠的 条评论
为什么被折叠?



