力扣(LeetCode)数据结构练习题

今天来分享两道力扣(LeetCode)的题目来巩固上篇时间复杂度和空间复杂度的知识,也就是在题目上加上了空间复杂度和时间复杂度的限制。

目录

[给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。](#给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。)

[给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略nums2 的长度为 n 。](#给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略nums2 的长度为 n 。)


给你一个数组 nums和一个值 val,你需要 原地 移除所有数值等于 val的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。


我们注意审题发现这里要求O(1)的空间复杂度来完成,且在原地修改数组。不知道大家是否有了自己思路了呢。这道题的考点就是限制了空间复杂度和操作方式,那么有什么办法呢,下面是一种参考方法。

cs 复制代码
int removeElement(int* nums, int numsSize, int val) {


    int a=0;
    int b=0;
while(a<numsSize)
{
if(nums[a]!=val)
{
    nums[b]=nums[a];
    b++;
    a++;
}
else
{
    a++;
}

}


return b;
}

具体思路:我们就创建两个变量作为解体的关键,其中a作为遍历数组全部的变量,不断往后遍历,知道数组的元素全部遍历完成,即a==numsSize。在此过程中只要nums数组中的元素不等于val我们就从头开始不断往后覆盖掉原来的数即可。

此解法空间复杂度位O(1),时间复杂度为O(N)。

接下来我们看第二题


给你两个按 非递减顺序 排列的整数数组 nums1nums2,另有两个整数 mn ,分别表示 nums1nums2 中的元素数目。

请你 合并 nums2nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意: 最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况
nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略
nums2 的长度为 n

这里我们尽量将代码弄到更优且我们试试将时间复杂度控制为O(m+n),下面给出一种参考解法:

cs 复制代码
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    
int end=m+n-1;
int end1=m-1;
int end2=n-1;
while(end1>=0 && end2>=0)
{
if(nums1[end1]>nums2[end2])
{

    nums1[end]=nums1[end1];
    end1--;
    end--;
}

else
{

nums1[end]=nums2[end2];
end2--;
end--;

}

}

while(end2>=0)
{

nums1[end]=nums2[end2];
end--;
end2--;

}


}

具体思路:这里我们从题目可知我们要将nums2合并到nums1中,其中nums1的长度为m+n,那么如果我们从nums1的前面开始排序,我们就会因为排序而丢失前面nums1原来的值,所以我们就要从末尾开始排序,所以我们在代码中先定义出三个整形变量end1,end2,end,分别进行运算,进行while循环在两个数组都没比较结束到首元素时我们进行比较后放入nums1的末尾,当有一个nums1的比较元素已经到首元素时,如果nums2的元素还没比较完,那么我们就需要将nums2的元素全排在前面即可。

这里的解法空间复杂度为O(m+n),空间复杂度为O(1)


好了就分享这两道题了,这两道题主要控制时间复杂度和空间复杂度是相比以前的练习解法限制更多,锻炼我们写优质代码的能力。喜欢的话希望点个心心支持一次唔。

相关推荐
_饭团21 小时前
指针核心知识:5篇系统梳理4
c语言·开发语言·c++·笔记·深度学习·算法·面试
YXXY31321 小时前
二分查找算法
算法
爱玩亚索的程序员21 小时前
算法入门(一)Python基础(list、dict、set、tuple、for、enumerate、lambda、sorted)
python·算法·list
一叶落43821 小时前
LeetCode 134. 加油站(贪心算法详解 + C语言实现)
c语言·数据结构·算法·leetcode·贪心算法
say_fall21 小时前
位运算底层逻辑与解题应用绪论
c++·学习·算法·leetcode·职场和发展
Σίσυφος190021 小时前
为什么 Generalized ICP(GICP)通常比 Point-to-Plane 更稳定?
算法
j_xxx404_21 小时前
常见位运算基础知识,技巧总结以及力扣实战
数据结构·c++·算法·leetcode
RuiBo_Qiu21 小时前
【LLM进阶-后训练&部署】1. 大语言模型全参数微调:从前向推理到反向传播的底层原理解析
人工智能·算法·语言模型·自然语言处理·ai-native
子有内涵21 小时前
【Linux】程序地址空间(是什么?为什么?)
linux·运维·算法
setmoon21421 小时前
C++与量子计算模拟
开发语言·c++·算法