1.题目要求
题目要求:
注意:要求是原地修改
题目说明:
题目示例:
![]()
2.题解
(1)前言
首先如果题目没有要求在原地修改我们应该怎么做?
思路一:创建一个顺序表,将nums数组中的每个值与val进行对比,如果等于val则add到顺序表中即可
思路二:我么们可以定义一个新的数组,新数组与原数组的大小一致,通过for循环来将数组中的每一个元素与val进行比较,当不相等的时候添加到新数组中。需要注意的是我们需要定义一个新数组的下标变量index的初始值为0,当我们第一次发现不等于val值时,我们就添加到新数组index下标的位置,然后我们index++,来存放下一次不等于val的值,依此循环。
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
int[] nums = {3,2,2,3};
int val = 3;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != val) {
integerList.add(nums[i]);
}
}
System.out.println(integerList);
}
public static void main(String[] args) {
int[] nums = {2,2,3,3,4};
int val = 2;
int[] newNums =new int[nums.length];
int index = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != val) {
newNums[index] = nums[i];
index++;
}
}
System.out.println(Arrays.toString(newNums));
}
(2)题解一
思路:
1. 创建一个长度与nums相同的数组ret 2. 遍历nums,将nums中所有与val不同的元素搬移到ret中 3. 将ret中所有元素拷贝回nums中
class Solution {
public int removeElement(int[] nums, int val) {
int[] ret = new int[nums.length];
int size = 0;
for(int i = 0; i < nums.length; ++i){
if(nums[i] != val){
ret[size++] = nums[i];
}
}
System.arraycopy(ret, 0, nums, 0, size);
return size;
}
}
(3)题解二
思路:
1. 设置一个变量count,用来记录nums中值等于val的元素的个数 2. 遍历nums数组,对于每个元素进行如下操作: a. 如果num[i]等于val,说明值为val的元素出现了一次,count++ b. 如果nums[i]不等于元素,将nums[i]往前搬移count个位置 因为nums[i]元素之前出现过count个值等于val的元素,已经被删除了 因此次数需要将nums[i]往前搬移 3. 返回删除之后新数组中有效元素个数
public int removeElement(int[] nums, int val) {
int count = 0;
for(int i = 0; i < nums.length; ++i){
if(nums[i] == val){
count++;
}else{
nums[i - count] = nums[i];
}
}
return nums.length - count;
}
}
(4)题解三
快慢指针解法
思路:
- 快的每次如果不是val都要赋值给慢的
- 每次slow被赋值后要往后移动
- 不论如何fast都要++,因为它一直要往前走
- slow本身就代表长度,因为最后一次被slow被赋值的时候是最大索引,而正好++,代表长度
public int removeElement(int[] nums, int val) {
int slow = 0; // 慢指针
int fast = 0; // 快指针
while (fast < nums.length) {
if (nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}