【LeetCode】删除有序数组中的重复项、合并两个有序数组

作者:一个喜欢猫咪的的程序员

专栏:《Leetcode》

喜欢的话:世间因为少年的挺身而出,而更加瑰丽。                                  ——《人民日报》


目录

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

88.合并两个有序数组:


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

26. 删除有序数组中的重复项https://leetcode.cn/problems/remove-duplicates-from-sorted-array/ 题目:


示例:

示例 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 。不需要考虑数组中超出新长度后面的元素。


 思路:

思路一:(双指针暴力解法)

利用双指针begin和end一前一后,每次begin和end相等时,设一个变量i=begin,利用i来将右边的值赋给左边,以此循环左边都是一次出现的值了。

初始条件:begin=0     end=1
结束条件:begin>=size||endsize||end==size-1的情况
迭代原理:
当nums[begin]=nums[begin+1]的时候,nums[i]=nums[i+1]向左覆盖,size--,另外的情况,nize--就可以了

时间复杂度:O(N^2)                                 空间复杂度:O(1)

思路二:双指针优化

还是利用两个指针,因为我们返回值个数,只检查前numsSize个值是否符合条件,但后面的值不管,所以我们可以这样。

当begin所值的值与end所指的值想同时,我们end后移一位,然后如果这两个值所指的值相等,继续此操作,如果不相等,先进行begin后移一位,然后将把end所指的值赋给begin所指的位置,然后end后移(如果不先begin++再赋值的话,会顺序不对)


思路一: 

int removeDuplicates(int* nums, int numsSize) {
    int begin = 0;
    int end = 1;
    while (begin < numsSize && end < numsSize)
    {
        while (nums[begin] == nums[begin+1])
        {
            if(end==numsSize-1)
            {
                numsSize--;
                break;
            }
            else
            {
            for (int i = end; i < numsSize-1; i++)
            {
                nums[i] = nums[i + 1];
            }
            numsSize--;
            }
        }
        begin = end;
        end++;
    }
    return numsSize;
}

 思路二:

int removeDuplicates(int* nums, int numsSize) {
int begin=0;
int end=1;
while(end<numsSize)
{
    if(nums[begin]==nums[end])
    ;
    else
    {
        begin++;
        nums[begin]=nums[end];
    }
    end++;
}
return begin+1;
}

88.合并两个有序数组:

88. 合并两个有序数组https://leetcode.cn/problems/merge-sorted-array/

 题目:


示例:

示例 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 中。


思路:

思路一: 利用额外数组法

将两个数组元素进行比较,较小的赋值给额外数组sort。

时间复杂度:O(m+n)                  空间复杂度:O(m+n)

思路二: 逆向双指针

我们在思路一的基础上优化,我们双指针一般是一前一后或者两个在头作比较,本题我们双指针两个都在后面,作比较哪个比较大再放在nums1的尾部,然后分别自减。这样就可以避免从前面作比较后造成的原nums1前面的元素丢失了。

时间复杂度:O(m+n)                  空间复杂度:O(1)


思路一:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    int q1 = 0;
    int q2 = 0;
    int sort[m + n];
    if (n == 0)
        ;
    else {
        for (int i = 0; i < m + n; i++)
        {
            if (q2 == n)
                sort[i] = nums1[q1++];
            else if (q1 == m)
                sort[i] = nums2[q2++];
            else  if (nums1[q1] > nums2[q2])
                sort[i] = nums2[q2++];
            else
                sort[i] = nums1[q1++];
        }
        for (int i = 0; i < m + n; i++)
        {
            nums1[i] = sort[i];
        }
    }
}

思路二:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    int end1=m-1;
    int end2=n-1;
    int i=n+m-1;
    while(end1>=0||end2>=0)
    {
        if(end2<0)
         nums1[i--]=nums1[end1--];
        else if(end1<0)
        nums1[i--]=nums2[end2--];
        else  if(nums1[end1]>nums2[end2])
        nums1[i--]=nums1[end1--];
        else
        nums1[i--]=nums2[end2--];
    }
}

  • 40
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 26
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学IT的小卢

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

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

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

打赏作者

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

抵扣说明:

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

余额充值