Leetcode - Remove Element

来源:互联网 发布:业主名录采集软件 编辑:程序博客网 时间:2024/04/30 14:22

Question

Given an array and a value, remove all instances of that value in place and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
The order of elements can be changed. It doesn’t matter what you leave beyond the new length.


Example

Given input array nums = [3,2,2,3], val = 3
Your function should return length = 2, with the first two elements of nums being 2.


Hint

1.Try two pointers.
2.Did you use the property of “the order of elements can be changed”?
3.What happens when the elements to remove are rare?


Java Code

//版本一public int removeElement(int[] nums, int val) {    if(nums.length == 0)        return 0;    int i = 0;    for(int j = 0; j < nums.length; ++j) {        if(nums[j] != val)           nums[i++] = nums[j];    }    return i;}//版本二public int removeElement(int[] nums, int val) {    if(nums.length == 0)        return 0;    int i = 0;    for(int j = nums.length - 1; i <= j; ++i) {          while(nums[j] == val) {            if(j == i || j == 0)                return j;            else                --j;           }        if(nums[i] == val )            nums[i] = nums[j--];    }    return i;}

说明

  • 本题的关键点有两个,一是只遍历一次数组,二是不使用额外的空间,所以“删除”操作只能在原数组中进行,但是数组的长度是不可变的,所以“删除”操作的实现方式有两种,一种是把需要删除的元素全部移动到数组的末端(即交换元素的位置),第二种是把所有无需删除的元素前移并覆盖掉需要删除的元素(不必使用元素交换)

  • 这里给出的算法均采用上述的第二种处理思路,且使用两个指针。

    1. 版本一中,指针i指向当前不包含目标元素val的最长子数组末位的下一位(该元素的值可能等于val,也可能不等于val),指针j用于遍历数组,如果其所指向的元素值不等于val,则用该元素的值覆盖掉指针i位置上的元素值(如果被覆盖的元素不等于val,则它在此之前已经被复制并保存到上述最长子数组中了,想想看为什么? j总是比i移动得快)

    2. 版本二中,与版本一的不同在于指针j从数组的末端开始遍历,while循环的作用是保证j指向的元素值不等于val。当指针i指向的元素值等于val时,用j对应的值覆盖掉i对应的值,相当于交换了i和j对应元素的值,但是实际操作中没必要交换。这种处理方式的好处在于可以避免不必要的数组元素复制(Hint中的第3点)

  • 当然本题也可以按照Hint中第2点提到的思路来做,也就是先排序,但应该是没有必要的

0 0