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

简介: 【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--];
    }
}
相关文章
|
2月前
leetCode(删除有序数组中的重复项)
如何在不使用额外空间的情况下,通过双指针法原地删除有序数组中的重复项。
38 2
|
4月前
|
存储 Java API
LeetCode------合并两个有序数组(4)【数组】
这篇文章介绍了LeetCode上的"合并两个有序数组"问题,并提供了三种解法:第一种是使用Java的Arrays.sort()方法直接对合并后的数组进行排序;第二种是使用辅助数组和双指针技术进行合并;第三种则是从后向前的双指针方法,避免了使用额外的辅助数组。
LeetCode------合并两个有序数组(4)【数组】
|
2月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
25 4
|
2月前
【LeetCode 48】108.将有序数组转换为二叉搜索树
【LeetCode 48】108.将有序数组转换为二叉搜索树
43 0
|
4月前
|
算法
LeetCode第26题删除有序数组中的重复项
这篇文章介绍了LeetCode第26题"删除有序数组中的重复项"的解题方法,通过使用双指针技巧,高效地去除数组中的相邻重复元素。
LeetCode第26题删除有序数组中的重复项
|
4月前
|
算法
LeetCode第80题删除有序数组中的重复项 II
文章介绍了LeetCode第80题"删除有序数组中的重复项 II"的解法,利用双指针技术在O(1)空间复杂度内原地删除重复元素,并总结了双指针技术在处理有序数组问题中的应用。
LeetCode第80题删除有序数组中的重复项 II
|
4月前
|
算法
LeetCode第88题合并两个有序数组
文章分享了LeetCode第88题"合并两个有序数组"的解法,通过从后向前的合并策略避免了数组元素的前移,使用三个指针高效地完成了合并过程。
|
4月前
|
Python
【Leetcode刷题Python】108. 将有序数组转换为二叉搜索树
LeetCode上108号问题"将有序数组转换为二叉搜索树"的Python实现,通过递归选取数组中间值作为根节点,构建高度平衡的二叉搜索树。
31 2
|
4月前
|
算法 Java
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
59 0
|
4月前
|
存储 算法 Java
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
48 0