Array篇easy难度之指定元素去重

题目描述

https://leetcode.com/problems/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.

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 a 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]);
}
 

Example 1:

Input: nums = [3,2,2,3], val = 3
Output: 2, nums = [2,2]
Explanation: 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. For example if you return 2 with nums = [2,2,3,3] or nums = [2,3,0,0], your answer will be accepted.
Example 2:

Input: nums = [0,1,2,2,3,0,4,2], val = 2
Output: 5, nums = [0,1,4,0,3]
Explanation: 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.
 

Constraints:

0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100

博主第一次提交的代码

解法比较直观,但是循环了n次,在discuss区还有很多优秀的解法给大家分享

class Solution {
    public int removeElement(int[] nums, int val) {
        if(nums == null){
            return 0;
        }
        int index = 0;
        for(int eachInt: nums){
            if(eachInt != val){
                nums[index] = eachInt;
                index++;
            }
            
        }
        return index;
    }
}

他人优秀的代码

解法一

int removeElement(int A[], int n, int elem) {
    int p = 0;
    int q = n - 1;
    while( p <= q )
    {
        if( A[p] != elem )
            p++;
        else if( A[q] == elem )
            q--;
        else
        {
            int tmp = A[p];
            A[p++] = A[q];
            A[q--] = tmp;
        }
    }

    return p;
}

这个解法看似好像不用全遍历所有元素,但是性能是一样的,评论区大佬也指出了这个问题


image.png

那么如何能解决这个问题呢,就是让他们同时更新

class Solution {
    public int removeElement(int[] nums, int val) {
        if(nums.length == 1 && nums[0] == val){
            return 0;
        }
        int p = 0;
        int q = nums.length - 1;
        
        while( p <= q )
        {
            if(!(nums[p] != val) && !(nums[q] == val))
            {
                int tmp = nums[p];
                nums[p++] = nums[q];
                nums[q--] = tmp;
            }
            
            if( nums[p] != val )
                p++;
            if( nums[q] == val )
                q--;
        }
        return p;
    }
}

解法二

其实和解法一一样,不过更加简洁

int removeElement(int A[], int n, int elem) {
    int i = 0;
    while (i < n) {
        if (A[i] == elem) {
            A[i] = A[n - 1];
            n--;
        }
        else
            i++;
    }
    return n;
}

总结

不论是哪个解法,其实时间复杂度都是相同的,都是基于大的时间复杂度下进行简单的时间优化

你可能感兴趣的:(Array篇easy难度之指定元素去重)