【数据结构】线性表相关Leetcode练习

本专栏使用C/C++语言编写数据结构
C语言专栏:C语言基本语法、基本操作、相关库函数的编写,相关内存分析
C++专栏:C++基本语法C++相关结构剖析,详细例题,相关小型Demo的编写
数据结构专栏:基本数据结构原理介绍,代码实现,相关Leetcode例题讲解剖析
干货满满,陆续更新ing

本文为与线性表相关的Leetcode题目

线性表

1. 存在重复元素

217. 存在重复元素

给你一个整数数组 nums。如果任一值在数组中出现至少两次,返回 true;如果数组中每个元素互不相同,返回false 。
示例 1:
输入:nums = [1,2,3,1]
输出:true
示例 2:
输入:nums = [1,2,3,4]
输出:false
示例 3:
输入:nums = [1,1,1,3,3,4,3,2,4,2]
输出:true

排序

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
    //对vector内数值进行排序
    sort(nums.begin(),nums.end());
    for(int i = 0;i<nums.size()-1;i++){
        if(nums[i]==nums[i+1]){
            return true;
        }
    }
    return false;
    }
};
时间复杂度:O(NlogN),其中N为数组的长度。需要对数组进行排序。
空间复杂度:O(logN),其中N为数组的长度。注意我们在这里应当考虑递归调用栈的深度。

2. 消失的数字

17.04. 消失的数字

数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。在O(n)时间内完成
示例 1:
输入:[3,0,1]
输出:2
示例 2:
输入:[9,6,4,2,3,5,7,0,1]
输出:8

哈希表

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        vector<int>num;
        num.assign(nums.size()+1,-1);
        for(int i = 0;i<nums.size();i++){
            num[nums[i]]=nums[i];
        }
        int i = 0;
        for(i = 0;i<num.size();i++){
            if(num[i]==-1){
                break;
            }
        }
        return i;
    }
};             

image-20230214194258831
如上图所示,初始化一个值全为-1的num数组,将nums中的值放到值对应下标的num中,最后遍历num,值为-1所对应的下标即为缺失的整数。

3. 删除有序数组中的重复项

26. 删除有序数组中的重复项

给你一个升序排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致 。
如果在删除重复项之后有k个元素,那么nums的前k个元素应该保存最终结果。
将最终结果插入nums的前k个位置后返回k。
在使用 O(1) 额外空间的条件下完成。
输入:nums = [1,1,2]
输出:2, nums = [1,2]
解释:函数应该返回新的长度2,并且原数组 nums 的前两个元素被修改为1, 2。不需要考虑数组中超出新长度后面的元素。
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int src = 0;
        int dst = 0;
        while(dst < nums.size()){
            if(nums[dst]!=nums[src]){
                src++;
                nums[src]=nums[dst];
            }else{
                dst++;
            }	
        }
        return src+1;
    }
};
时间复杂度:O(N),其中N是数组的长度。
空间复杂度:O(1),只需要使用常数的额外空间。

4. 合并两个有序数组

88. 合并两个有序数组

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

归并思想

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = m-1, j = n-1;
        int dst = m+n-1;
        while(i >= 0 && j >= 0){
            if(nums1[i] > nums2[j]){
                nums1[dst--] = nums1[i--];
            }else{
                nums1[dst--] = nums2[j--];
            }
        }
        while(j >= 0){
            nums1[dst--] = nums2[j--];
        }
    }
};
第一种情况:

(1)i与j分别为nums1与nums2的最后一个有效元素的下标,dst为nums1数组最后一个元素的下标,比较nums1[i]与nums2[j]的大小,将较大的值赋值给nums1[dst],同时,移动指针。
因为数组中的元素为递增存放,故每次比较将较大的元素赋值给nums1[dst]。
image-20230214194319396
(2)移动dst与j,进行赋值
image-20230214194331140
(3)nums1[i] > nums2[j],故将较大值nums1[i]赋值给nums1[dst]。
image-20230214194349852
(4)nums1[i]==nums2[j];根据代码,将进入else分支,将nums1[j]赋值给nums1[dst]。

image-20230214194405485

第二种情况:

(1)第二种情况中,nums1中所有元素均大于nums2中的元素,进行比较,将较大值存放于dst指向的数组中。
image-20230214194418739
(2)依次进行比较,赋值,挪动双指针。
image-20230214194429462
(3)由下图可知,当nums1中的元素全部都比较结束后,需要将nums2中的元素全部都赋值到nums1中。
image-20230214202006804
(4)如下图所示,赋值完成,合并数组完成。

image-20230214194456431
看到这里,如果感觉文章对你有帮助,不要忘记一键三连哦!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Miraitowax

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值