算法之移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 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。
你不需要考虑数组中超出新长度后面的元素。
注意数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
推荐方法:
双指针法
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置
package com.array;
/**
* 移除元素----快慢指针
*
* 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
* @author 26736
*
*/
public class RemoveFactor {
public static void main(String[] args) {
Test t=new Test();
int num[]=new int[] {1,1,2,4,5,6,8};
int val=1;
int length=t.remove(num, val);
System.out.println(length);//5
int num1[]=new int[] {1,2,5,6,6,6,7};
int aim=6;
int length1=t.remove1(num1, aim);
System.out.println(length1);//4
}
}
class Test {
/**
* 方法一:暴力解法
*
* 使用2个for循环嵌套:
*时间复杂度:O(n^2)
*空间复杂度:O(1)
* @param arr
* @param val
* @return
*/
public int remove(int[] arr,int val) {
//首先获取数组的长度size
int size=arr.length;
//外层for循环:遍历数组arr
for(int i=0;i<arr.length;i++) {
//判断外层循环是否找到目标值,如果找到,就进行以下操作
if(arr[i]==val) {
//内层for循环:覆盖目标值
for(int j=i+1;j<arr.length;j++) {
arr[j-1]=arr[j];
}
//因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
i--;
//长度减一
size--;
}
}
//返回数组长度
return size;
}
/**
* 方法二:
* 双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作
* 定义快慢指针:
快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
慢指针:指向更新 新数组下标的位置
* 时间复杂度:O(n)
* 空间复杂度:O(1)
* @param arr
* @param val
* @return
*/
public int remove1(int arr[],int val) {
//定义慢指针
int slow=0;
//声明快指针
int fast;
//快指针开始遍历数组
for(fast=0;fast<arr.length;fast++) {
//如果快指针索引对应的值不等于要删除的值
if(arr[fast]!=val) {
//就将快指针所遍历的值赋给慢指针,慢指针此时为0
arr[slow]=arr[fast];
//慢指针得到快指针赋的值,就向前加一(可知慢指针前进的条件就是快指针遍历到满足要求的值) 满足要求的值就是arr[fast]!=val
slow++;
}
}
//返回慢指针就是数组长度
return slow;
}
}
学习自代码随想录在这里插入代码片