顺序表算法题(LeetCode)

1 移除元素

代码示例:

c 复制代码
int removeElement(int* nums, int numsSize, int val) {
    int left = 0;
    for( int right = 0;right<numsSize;right++)
    {
        if(nums[right]!=val)
        {
            nums[left++]=nums[right];
        }
    }
    return left;
}

代码详细说明:

我们定义了两个变量leftrightleft作为标定位表示在它前面的元素都不为valright则作为判断位一直向后面找不为val的元素

建立一个for循环让right一直走到数组最后一个位置

c 复制代码
 for( int right = 0;right<numsSize;right++);

如果right指向的数组元素不等于val则让right指向数组元素赋值给left指向的下标,如果等于val则不做任何处理

c 复制代码
 if(nums[right]!=val)
        {
            nums[left++]=nums[right];
        }
    }

最后left则为不等于val的数组元素数,将其返回

c 复制代码
 return left;

小结:本题采用两个指针(不是C语言的指针,表示指向数组位置的意思)leftrightright指针负责遍历,而left指针确定要修改的位置,如果遇到数组元素一直不为val,则两者一起移动,如果遇到valleft停下来,直到right指针找到不为val的值将其赋值给left指针位置。

2 删除有序数组中的重复项

代码示例:

c 复制代码
int removeDuplicates(int* nums, int numsSize) {
    int left ,right;
    left = 0;
    right = left+1;
    while(right<numsSize)
    {
        if(nums[left]!=nums[right])
        {
            left++;
          nums[left]=nums[right]; 
        }
       right++;
    }
    return left+1;
}

代码详细说明:

本题数组是一个非严格递增函数(即前面元素<=后面元素),面对这个数组删除重复项,依旧是采用两个指针leftrightleft指针由于锁定位置要改变的位置,而right则向后遍历找不等于left指向的元素与其交换。

首先,让left指向第一个元素下标,right指向left后面的一个位置,right=left+1

c 复制代码
left = 0;
right = left+1;

right指针直到最后一个数组元素后面时则循环结束

c 复制代码
while(right<numsSize)

在循环体中如果left指针指向内容与right相同时则只right指针移动,只有当left指向数组元素大小与rightleft指针才会向后一位并将right指向内存赋值给left指针指向区域。

c 复制代码
 if(nums[left]!=nums[right])
        {
            left++;
          nums[left]=nums[right]; 
        }
       right++;
    }

由于left是数组下标,所以返回实际元素个数时需要+1

c 复制代码
return left+1;

最后说明:题目对数组元素大小限制非空,所以不存在数组元素大小为0的情况。

3 合并两个有序数组

代码示例:

c 复制代码
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    int s1_right = m+n-1;
    int s1_left =  m-1;
    int s2_right = n-1;
    while(s1_left>=0&&s2_right>=0)
    {
        if(nums2[s2_right]>=nums1[s1_left])
        {
            nums1[s1_right]=nums2[s2_right];
            s2_right--;
        }
        else
        {
            nums1[s1_right]=nums1[s1_left];
            s1_left--;
        }
        s1_right--;
    }
    //当有剩余的数组时
    while(s2_right>=0)
    {
       nums1[s1_right]=nums2[s2_right];
        s1_right--;
        s2_right--; 
    }
}

代码总体思路:由于两个数组元素都是非递减序列,并且我们最后也要保证改变后的nums1也是非递减序列,所以我们可以从nums1的最后一个位置开始赋值元素,即从后往前改变nums1数组,这样的设计也不会改变nums1的前面元素。我们取出从后往前取出nums1nums2的元素并比较大小将大的往nums1后面放。直到一个数组的元素全部放完,如果放完的是nums1则直接将剩下的nums2元素依次赋值到nums1前面就行了,如果是nums2放完则不用改变什么。

代码详细讲解:

创建三个指针分别指向

c 复制代码
    int s1_right = m+n-1;
    int s1_left =  m-1;
    int s2_right = n-1;

当其中一个数组元素被遍历完之后则跳出循环

c 复制代码
while(s1_left>=0&&s2_right>=0)

在循环体里面nums1nums2后面元素比较大小,并将较大值赋值给nums1[s1_right],并更新指针指向。

c 复制代码
if(nums2[s2_right]>=nums1[s1_left])
        {
            nums1[s1_right]=nums2[s2_right];
            s2_right--;
        }
        else
        {
            nums1[s1_right]=nums1[s1_left];
            s1_left--;
        }
        s1_right--;

当其中一个数组遍历完成时,如果是nums1被遍历完则直接将nums2剩余元素全部放到nums1数组中

c 复制代码
    while(s2_right>=0)
    {
       nums1[s1_right]=nums2[s2_right];
        s1_right--;
        s2_right--; 
    }

由于题目设计nums1的数组大小是正好装的下两个数组全部元素的,所以在添加nums2元素到nums1中是不会覆盖和改变nums1元素的,除非当前位置nums1元素已经被拿到s1_right指针处赋值过了。

相关推荐
weisian1515 分钟前
基础篇--概念原理-2-参数是什么?——从原理到实战,一篇讲透
面试·职场和发展·模型参数·7b和70b·参数=规则,不是原始数据
王老师青少年编程11 分钟前
csp信奥赛C++高频考点专项训练之贪心算法 --【贪心与二分判定】:数列分段 Section II
c++·算法·贪心·csp·信奥赛·二分判定·数列分段 section ii
V搜xhliang024632 分钟前
OpenClaw科研全场景用法:从文献到实验室的完整自动化方案
运维·开发语言·人工智能·python·算法·microsoft·自动化
天真小巫44 分钟前
2026.5.2总结
职场和发展
汉克老师1 小时前
GESP2025年3月认证C++五级( 第三部分编程题(2、原根判断))
c++·算法·模运算·gesp5级·gesp五级·原根·分解质因数
weisian1511 小时前
基础篇--概念原理-1-Token是什么?——从原理到实战,一篇讲透
人工智能·职场和发展·token
数据皮皮侠1 小时前
上市公司创新韧性数据(2000-2024)|顶刊同款 EIR 指数
大数据·人工智能·算法·智慧城市·制造
WL_Aurora1 小时前
Python 算法基础篇之链表
python·算法·链表
科研前沿1 小时前
纯视觉无感解算 + 动态数字孪生:室内外无感定位技术全新升级
大数据·人工智能·算法·重构·空间计算
Wadli2 小时前
26.单调栈
算法