LeetCode27_Remove Element

这道题并不要求输出数组的顺序,所以难度降低了不少。

Given an array nums and a value val, 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 by modifying the input array in-place with O(1) extra memory.

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

Example 1:

Given nums = [3,2,2,3], val = 3,

Your function should return length = 2, with the first two elements of nums being 2.

It doesn't matter what you leave beyond the returned length.

Example 2:

Given nums = [0,1,2,2,3,0,4,2], val = 2,

Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4.

Note that the order of those five elements can be arbitrary.

It doesn't matter what values are set beyond the returned length.

Clarification:

Confused why the returned value is an integer but your answer is an array?

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

Internally you can think of this:

// nums is passed in by reference. (i.e., without making a copy)
int len = removeElement(nums, val);

// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

最开始的代码出现的两个问题:

int removeElement(int* nums, int numsSize, int val) {
    int i,j,temp,count=0;
    for(i=0;i<numsSize;i++){
        if(nums[i]==val){
            count++;
            for(j=numsSize-1;j>=0;j--){//这边j>=0是不对的,应该j>i使得j在i后面,否则就前后循环互换肯定出错
                if(nums[j]!=val)break;
            }
            temp=nums[i];
            nums[i]=nums[j];
            nums[j]=temp;     
        }
    }

    return numsSize-count+1;//计数有很大的问题:首先+1的确是有问题的,其次前后互换之后,被换到后面的val还是会被计数一次,所以存在重复计数的问题。解决的方法是记下前后互换的次数,将计数的count里减去前后互换次数,就是实际等于val的个数。

}

修改后的代码如下:

int removeElement(int* nums, int numsSize, int val) {
    int i,j,temp,count1=0,count2=0;
    for(i=0;i<numsSize;i++){
        if(nums[i]==val){
            count1++;
            for(j=numsSize-1;j>i;j--){
                if(nums[j]!=val){
                    count2++;
                    break;}
            }
            temp=nums[i];
            nums[i]=nums[j];
            nums[j]=temp;     
        }
    }
    return numsSize-count1+count2;//返回numsSize-count1+count2,真的用数组验证一下,不要想当然
}

自己写了一个java版本,效果还可以。

class Solution {
    public int removeElement(int[] nums, int val) {
        int i,temp;
        int count=0;
        if(nums.length==0){return 0;}
        for(i=nums.length-1;i>=count;--i){//这边以i>=count控制了循环次数,如果从前往后遍历的话也是可以的,就识别了val换过去,然后从被换的位置i--再扫描一次。
            if(nums[i]!=val){
                temp=nums[count];
                nums[count]=nums[i];
                nums[i]=temp;
                count++;
                i++;//需要注意的是,互换之后的数组,应该从被换的地方重新遍历,因为可能被换过去的那个数值也不符合val
            }
        }
        return count;
    }
}

猜你喜欢

转载自blog.csdn.net/lilililililydia/article/details/80966710