【算法】数组合并去重算法

简介: 【算法】数组合并去重算法

删除有序数组重复项

由于数组是有序的,因此只要判断当前数组元素是否与下一个数组元素相等即可,如果相等,那么就继续向后遍历,直到遇到一个不相等的。然后我们可以将这个不相等的,覆盖到第一个重复元素的位置处,这样子就能在不创建一个临时数组的情况下,直接在原数组进行拷贝了。

遇到这种数组去重,删特定值的时候,并且要求不能有新数组,那么一般可以考虑双指针。

也就是定义两个指针,一个slow指针,表示的是不重复元素下一次可以插入的位置,fast用于遍历数组,找出不重复元素。

这里从下标1开始或者从下标0开始都是可以的。

public int removeDuplicates(int[] nums) {
        int n = nums.length;
        if (n == 0) {
            return 0;
        }
        int fast = 1, slow = 1;
        while (fast < n) {
            if (nums[fast] != nums[fast - 1]) {
                nums[slow] = nums[fast];
                ++slow;
            }
            ++fast;
        }
        return slow;
    }

删除特定值

既然也是不能创建临时数组,那么就要考虑把特定值给他覆盖掉。

由于要求删除数组中等于 val 的元素,因此输出数组的长度一定小于等于输入数组的长度,我们可以把输出的数组直接写在输入数组上。可以使用双指针:右指针fast指向当前将要处理的元素,左指针slow指向下一个将要赋值的位置。

如果右指针指向的元素不等于 val,它一定是输出数组的一个元素,我们就将右指针指向的元素复制到左指针位置,然后将左右指针同时右移;

如果右指针指向的元素等于 val,它不能在输出数组里,此时左指针不动,右指针右移一位。

也就是,如果遍历的指针(右指针)遇到的值等于val,那么直接忽略,但是如果遇到的值不是,那么就把这个值覆盖到左指针指向的位置。

public int removeElement(int[] nums, int val) {
        int slow = 0;//双指针 slow代表的是非val值可以插入的下一个位置
        int fast = 0;//fast用于遍历
        int n=nums.length;
        while (fast<n){
            if (nums[fast]!=val){
                nums[slow++]=nums[fast];
            }
            fast++;
        }
        return slow;
    }

有序数组合并

已知两个有序数组,其中第一个有序数组的元素个数为m,第二个有序数组的个数为n。

因此为了能在第一个数组上直接对两个数组进行合并,那么第一个数组的大小应该设定为m+n,也就是合并之后的总大小。

之后,就可以开始考虑如何把两个数组进行合并了。其中第一个数组的尾部的数据均为0,长度为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] ,其中斜体加粗标注的为 nums1 中的元素。

考虑到当前数组1的尾部有空余元素,因此可以考虑尾插法,从两个数组的有效数据的尾部开始遍历,把更大的数据放在数组的尾部,这样子就能节省一个临时数组了。

//    public static void merge(int[] nums1, int m, int[] nums2, int n) {
//        for (int i=m,j=0;i<nums1.length;i++){
//            nums1[i]=nums2[j++];
//        }
//        Arrays.sort(nums1);
//    }
    public static void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1 = m - 1, p2 = n - 1;
        int tail = m + n - 1;
        int cur;
        while (p1 >= 0 || p2 >= 0) {
            if (p1 == -1) {
                cur = nums2[p2--];
            } else if (p2 == -1) {
                cur = nums1[p1--];
            } else if (nums1[p1] > nums2[p2]) {
                cur = nums1[p1--];
            } else {
                cur = nums2[p2--];
            }
            nums1[tail--] = cur;
        }
    }

链表去重合并算法


相关文章
|
2月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
46 0
|
4月前
|
算法 测试技术
【算法】二分算法——寻找旋转排序数组中的最小值
【算法】二分算法——寻找旋转排序数组中的最小值
|
4月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
2月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
48 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
2月前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
29 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
6月前
|
存储 算法 Go
算法学习:数组 vs 链表
算法学习:数组 vs 链表
82 0
|
4月前
|
存储 算法 Java
深入算法基础二分查找数组
文章深入学习了二分查找算法的基础,通过实战例子详细解释了算法的逻辑流程,强调了确定合法搜索边界的重要性,并提供了Java语言的代码实现。
深入算法基础二分查找数组
|
4月前
|
算法
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
|
4月前
|
算法
【算法】模拟算法——外观数组(medium)
【算法】模拟算法——外观数组(medium)
|
4月前
|
算法
【算法】前缀和——除自身以外数组的乘积
【算法】前缀和——除自身以外数组的乘积

热门文章

最新文章