LeetCode----移除数组重复元素

移除元素

题目1:删除有序数组中的重复元素

要求:重复元素只出现一次,最后返回新数组的长度,不能使用额外的数组,必须原地修改,仅使用O(1)的额外空间。

解题思路:双指针法
  首先我们可以定义两个指针,一个快指针,一个慢指针。慢指针初始位置在nums[0],快指针初始位置在nums[1]。然后比较两个指针所在位置对应的值,如果相等,则快指针后移一位,慢指针不动;如果不相等,就把快指针当前值赋值给慢指针后一位,然后慢指针后移一位…直到快指针遍历完原始数组为止。最后返回 慢指针下标+1

本人代码:
class Solution {
    public int removeDuplicates(int[] nums) {
        int i = 0;
        for (int j = 1; j < nums.length; j++) {
            if (nums[i] != nums[j]) { 
                nums[i+1] = nums[j];
                i++;
            }
        }
        return i+1; 
    }
}

如果看代码比较抽象的话,可以画图来理解,同时也可以检测代码是否正确

题目2:移除数组中指定的元素

要求: 去掉数组中所有的指定元素,不能使用额外的数组空间,仅使用O(1)的空间并原地修改数组,最后返回新数组的长度,元素顺序可以更改

解题思路
方法一:双指针法
  这种方法跟上面那题几乎是一样,只要拿捏好两个指针的下标就行,这里不再赘述,给出AC代码。

class Solution {
    public int removeElement(int[] nums, int val) {
        int i = 0;
        for (int j = 0; j < nums.length; j++) {
            if (val != nums[j]) {
                nums[i] = nums[j];
                i++;
            }
        }
        return i;
    }
}

方法二:双指针之互换元素法
  简单讲一下这种方法,这种方法其实也是双指针,但它是更为效率的双指针。举个简单的例子:假定给出的数组为nums[1,2,3,4,5],val = 5,此时按方法一求解的话是做了一些无用的赋值操作的。相当于前四个元素都做了一遍自身赋值给自身的过程,方法二就是为了解决这个弊端。
  我们可以这么想,当nums[i] == val时,我们把nums中最后一个元素赋值给nums[i],并把最后一个元素释放掉;如果nums[i] != val,就仅仅让i++,不进行重新赋值的过程

这里给出AC代码

public int removeElement(int[] nums, int val) {
    int i = 0;
    int n = nums.length;
    while (i < n) {
        if (nums[i] == val) {
            nums[i] = nums[n - 1];
            // 并把数组长度减一
            n--;
        } else {
            i++;
        }
    }
    return n;
}

这里面有几个地方解释一下
1.while(i < n )这里面i < n 的条件是因为,i是下标,n是长度,下标一定要小于长度
2.第一个if里面不能对下标i做数值加减操作,是因为要验证数组最后一位值是否为题目中所要的val
3.最后返回n,是因为换元素的过程中数组末尾元素没有去掉,但我们取长度为n的数组即为题目所要的新数组

写在最后
题目较为简单,大佬请略过,本人只是为了梳理所学的知识,仅做总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值