27. 移除元素 - 力扣(LeetCode)
思路一
利用顺序表中的SLDestroy函数的思想,遇到等于val值的就挪动
思路二
双指针法:不停的将和val不相等的数字往前放。此时的des更像一个空数组,里面存放的都是和val不相等、能够存放的数字
src不等的时候才放,这样让所有和val不相等的数字都放进“dst指着尾巴的数组”去了
src是源数据,dst是目标位置
int removeElement(int* nums, int numsSize, int val) {
//双指针法
int src=0;
int dst=0;
while(src<numsSize){
if(nums[src]==val){
src++;
}else {
nums[dst++]=nums[src++];
}
}
return dst;
}
实现如上。
88. 合并两个有序数组 - 力扣(LeetCode)
思路一:
直接使用循坏合并,再用qsort(qsort永存!)
int int_compare(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) {
//暴力qsort
for(int i=m,q=0;i<m+n;i++,q++){
nums1[i]=nums2[q];
}
qsort(nums1,m+n,sizeof(nums1[0]),&int_compare);
}
思路2:
因为想从空白位置开始放(这样才能边放边比较),所以倒着从屁股开始放并且找“大”
每塞进去一个,相应的(l1或者l2)下标就减少一个
不用担心l3和l1撞到一起:1. 如果是将l2塞进空白位置,只有当全部只塞l2的时候才会出现l3和l1重合的情况(因为nums1的长度是经过计算的m+n,详情见题目)
2.如果是将nums1自己的元素塞在了数组末尾,也不用担心,因为l3和l1同时--,永远不会相遇
但是这样的特殊情况:l1都出去了,nums2还没有都塞进去,这就说明nums1中剩余的没有被替换的数据一定是非降序并且大于等于nums2中没有放进去的数据,所以再使用一个正序的循坏塞进nums1即可
实现如下:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
//暴力qsort
// for(int i=m,q=0;i<m+n;i++,q++){
// nums1[i]=nums2[q];
//}
//qsort(nums1,m+n,sizeof(nums1[0]),&int_compare);
//已通过测试
//逆向插入
int pos1,pos2,pos3;
pos1=m-1;//point to the end of nums1
pos2=n-1;//point to the end of nums2
pos3=m+n-1;//point to the end of m+n
while(pos1>=0&&pos2>=0){
if(nums1[pos1]<nums2[pos2]){
nums1[pos3]=nums2[pos2];
pos3--,pos2--;
}else{
nums1[pos3]=nums1[pos1];
pos3--,pos1--;
}
}
for(;pos2>=0;pos2--){
nums1[pos2]=nums2[pos2];
}
}
2.顺序表延伸的相关思考
1.顺序表的头插和尾差时间复杂度是O(N)
2.增容势必造成浪费,拷⻉数据,释放旧空间。会有不⼩效率的消耗。
同时,增容都是成倍的增长,假如我原有一百个空间,只需要增加一个空间,就会扩容到两百个空间,造成很多浪费。
那么,有没有一种数据结构可以解决以上的问题呢?