27. 移除元素

力扣题目链接(opens new window)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 移除元素java 移除元素暴力_leetcode 额外空间并原地修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。

示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

你不需要考虑数组中超出新长度后面的元素。

思考

方法一:

采用暴力法也不是无脑暴力法

  • 设置变量valcount表示:目前在数组结尾的val值的个数
  • 第一层for循环
  • 第一层开始条件 i = 0
  • 第一层结束条件 i < nums.length - valcount ,不用去查看结尾是val的数了
  • 当 nums[ i ] ==val时,第二层for循环
  • 第二层开始条件 j = nums.length - count - 1 , 因为已知结尾有valcount个val,所以从 nums.length - count - 1开始寻找数组最末尾并且值不是val的数以便进行交换
  • 如果当前 j 指向的数等于valcount,valcount++, 并且此时j-1 == i时,从j = nums.length - count - 1到 i这些数都等于val ,所以此时返回 nums.length-valcount-1(这个1是i指向的val)
  • 如果找到一个数不等于valcount,交换并break;
  • 第二层结束条件 j>i
  • 第二层循环结束代表已经找到结尾一个不为val的数值并且成功交换,所以数组最末尾val的个数+1

方法二:

双指针法:left ,right

这里0 - left中无val值,遍历数组即可

实现

方法一:

package 力扣;

public class leetcode27 {
    public static void main(String[] args) {
        int[] nums={0,1,2,2,3,0,4,2};
        int i = removeElement(nums, 2);
        System.out.println(i);
    }
    public  static int removeElement(int[] nums, int val) {
        // 这里定义为 数组末尾已知的连续的val个数
        int valcount=0;
        // i < nums.length-valcount ,肯定不用查看后面的无用信息了
        for (int i = 0; i < nums.length-valcount; i++) {
            if(nums[i]==val){
                int count=valcount;
                // j从已知末尾val的前一个数开始,向前寻找一个值不等于val的数进行交换
                for (int j=nums.length-1-count;j>i;j-- ){
                    // 如果末尾的值还是val 
                    if(nums[j]==val) {
                        valcount++;
                        // 如果此时已经到i前一个数还没找到值不等于val的数 这里-1的1代表i指向的val
                        if((j-1)==i) return nums.length-valcount-1;
                    }
                    // 找到值等于val的数
                    if(nums[j]!=val){
                        nums[i]=nums[j];
                        nums[j]=val;
                        break;
                    }
                }
                // 成功交换 末尾val数加一
                valcount++;
            }
        }
        return nums.length-valcount;
    }
}

方法二:

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