• 【数据结构与算法】OJ题--来源力扣


    作者:旧梦拾遗186

    专栏:数据结构成长日记

     

    每日励志

    如果有一天,你的努力配得上你的梦想,那么你的梦想也绝对不会辜负你的努力。

    前言:

    小编带大家刷力扣。

    目录

    移除元素

    题目描述:

    题解:

    删除有序数组中的重复项

     题目:

    题解: 

    合并两个有序数组 

    题目:

    题解:


    移除元素

    移除元素icon-default.png?t=M666https://leetcode.cn/problems/remove-element/

    题目描述:

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

    不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

    元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

    说明:

    为什么返回数值是整数,但输出的答案是数组呢?

    请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

    你可以想象内部操作如下:

    1. // nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
    2. int len = removeElement(nums, val);
    3. // 在函数里修改输入数组对于调用者是可见的。
    4. // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
    5. for (int i = 0; i < len; i++) {
    6.     print(nums[i]);
    7. }

    示例 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],也会被视作正确答案。

    示例 2:

    输入:nums = [0,1,2,2,3,0,4,2], val = 2
    输出:5, nums = [0,1,4,0,3]
    解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

    提示:

    • 0 <= nums.length <= 100
    • 0 <= nums[i] <= 50
    • 0 <= val <= 100

    题解:

    思路1:不开辟额外数组,在原有的数组上进行操作,把上面开辟的数组看成原来的数组,定义两个变量src和dst,当nums[val] != val的时候,我们直接让src继续走下去,dst继续走下去。出现等于val的时候,我们让src继续走下去,直接跳过即可:

    1. int removeElement(int* nums, int numsSize, int val){
    2. int src=0;
    3. int dst=0;
    4. while(src
    5. {
    6. if(nums[src]!=val)
    7. {
    8. nums[dst]=nums[src];
    9. dst++;
    10. src++;
    11. }
    12. else
    13. {
    14. src++;
    15. }
    16. }
    17. return dst;

     

    思路2:开辟一个数组,遍历如果不等于val就放到数组里面,最后将数组的元素赋值给原来的数组即可,但是时间复杂度不符合O(1): 

    1. int removeElement(int* nums, int numsSize, int val){
    2. int temp[100]={0};
    3. int i=0;
    4. int j=0;
    5. for(i=0;i
    6. {
    7. if(nums[i]!=val)
    8. {
    9. temp[j]=nums[i];
    10. j++;
    11. }
    12. }
    13. for(i=0;i
    14. {
    15. nums[i]=temp[i];
    16. }
    17. return j;
    18. }

     

    删除有序数组中的重复项

    删除有序数组中的重复项icon-default.png?t=M666https://leetcode.cn/problems/remove-duplicates-from-sorted-array/

     题目:

    给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。

    由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

    将最终结果插入 nums 的前 k 个位置后返回 k 。

    不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

    判题标准:

    系统会用下面的代码来测试你的题解:

    1. int[] nums = [...]; // 输入数组
    2. int[] expectedNums = [...]; // 长度正确的期望答案
    3. int k = removeDuplicates(nums); // 调用
    4. assert k == expectedNums.length;
    5. for (int i = 0; i < k; i++) {
    6. assert nums[i] == expectedNums[i];
    7. }

    如果所有断言都通过,那么您的题解将被 通过

    示例 1:

    输入:nums = [1,1,2]
    输出:2, nums = [1,2,_]
    解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
    示例 2:

    输入:nums = [0,0,1,1,1,2,2,3,3,4]
    输出:5, nums = [0,1,2,3,4]
    解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

    提示:

    • 1 <= nums.length <= 3 * 104
    • -104 <= nums[i] <= 104
    • nums 已按 升序 排列

    题解: 

    1. int removeDuplicates(int* nums, int numsSize){
    2. int dst=0;
    3. int src=1;
    4. while(src
    5. {
    6. if(nums[src]==nums[dst])
    7. {
    8. src++;
    9. }
    10. else
    11. {
    12. dst++;
    13. nums[dst]=nums[src];
    14. src++;
    15. }
    16. }
    17. return dst+1;
    18. }

     

     

    合并两个有序数组 

    合并两个有序数组icon-default.png?t=M666https://leetcode.cn/problems/merge-sorted-array/

    题目:

    给你两个按 非递减顺序 排列的整数数组 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 中的元素。
    示例 2:

    输入:nums1 = [1], m = 1, nums2 = [], n = 0
    输出:[1]
    解释:需要合并 [1] 和 [] 。
    合并结果是 [1] 。
    示例 3:

    输入:nums1 = [0], m = 0, nums2 = [1], n = 1
    输出:[1]
    解释:需要合并的数组是 [] 和 [1] 。
    合并结果是 [1] 。
    注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。
     

    提示:

    nums1.length == m + n
    nums2.length == n
    0 <= m, n <= 200
    1 <= m + n <= 200
    -109 <= nums1[i], nums2[j] <= 109
     

    进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?

    题解:

    思路1:不开辟新的空间,倒着进行数的大小进行比较,取大放在num1后面的位置中,在往前走。当数组num2结束了,那就结束了。当num1先结束,另外在进行处理。

    1. void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    2. int end1=m-1;
    3. int end2=n-1;
    4. int i=n+m-1;
    5. while(end1>=0&&end2>=0)
    6. {
    7. if(nums1[end1]
    8. {
    9. nums1[i]=nums2[end2];
    10. i--;
    11. end2--;
    12. }
    13. else
    14. {
    15. nums1[i]=nums1[end1];
    16. end1--;
    17. i--;
    18. }
    19. }
    20. while(end2>=0)
    21. {
    22. nums1[i]=nums2[end2];
    23. end2--;
    24. i--;
    25. }
    26. }

     

    思路1:开辟一个新的数组,遇到小的数就存放进去,当其中一个数组放完之后,另一个数组的元素在存放进去,最后在把新数组的元素拷贝到num1中,但是这中做法的时间复杂度是O(m+n),空间复杂度也是O(m+n):

     

    1. void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    2. int*tmp = malloc(sizeof(int)*(m+n));
    3. int i1 =0,i2=0;
    4. int i = 0;
    5. while(i1
    6. {
    7. if(nums1[i1]
    8. {
    9. tmp[i] = nums1[i1];
    10. ++i;
    11. ++i1;
    12. }
    13. else
    14. {
    15. tmp[i] = nums2[i2];
    16. ++i;
    17. ++i2;
    18. }
    19. }
    20. while(i1
    21. {
    22. tmp[i] = nums1[i1];
    23. ++i;
    24. ++i1;
    25. }
    26. while(i2
    27. {
    28. tmp[i] = nums2[i2];
    29. ++i;
    30. ++i2;
    31. }
    32. memcpy(nums1,tmp,sizeof(int)*(m+n));
    33. }

     

     

  • 相关阅读:
    力扣(LeetCode)901. 股票价格跨度(C语言)
    SpringCloud Sentinel集成Gateway和实时监控
    Python编程基础(华为在线课程)
    数字化底层逻辑揭秘!探寻地产工程行业发展新范式
    【每日练习系列】—— 滑动窗口与数学模拟
    大学时光仅四年,疫情反反复复占几年
    Vuex使用一文搞懂
    二叉树 | 所有路径 | 迭代&回溯 | leecode刷题笔记
    java计算机毕业设计喜枫日料店自助点餐系统源码+lw文档+系统+数据库
    【sfu】rtc 入口
  • 原文地址:https://blog.csdn.net/weixin_67900732/article/details/126134015