上面也是一道比较简单的题,之所以最近出的题都普遍比较简单就是,我计划现在是从基础题刷起,慢慢的我们就要上难度了,你们可要准备好哦。
好了,回归正题,对于这道题,我给出了三种解法:分别是:暴力解法,双指针法,和左右指针法(这里你可能会问:你最近为什么都是用java写代码呢?那java 中不是没有指针吗?我的回答:我之所以用java写,主要是我最近不是刚学吗,想趁机练一下,但是底层内容确实和c语言差不了多少,只要学过c语言一般就能看懂,另外对于java中的指针的说法,确实java中确实没有指针,但是我说的双指针指的是一种和指针类似的思想,所以他叫双指针法,在下面我也会重点讲这一种方法,因为这一种方法一般来说,是你们最不熟悉的),我们先上代码:
1.暴力解法
public int removeElement(int[] nums,int val){
int count = 0;
for(int i =0 ;i < nums.length; i++){
if(nums[i] == val){
for (int j = i; j < nums.length -1; j++) {
nums[j] = nums[j + 1];// 发现需要移除的元素,就将数组集体向前移动⼀位
}
i--;//这里要注意每次把数组向前移动一位,就要将i--一次,不然就会发生漏掉元素的情况
count++;//这里是为了记录究竟删除了多少元素
}
}
return nums.length - count;//这里将总元素减去我们已经删掉的元素就是我们的现有元素了
}//这种方法虽然好理解,但是在力扣上会超时
看完这个题后,此时我们再看一下题目,其实也很好理解,就还是无论我们把这个数组用什么方法怎么删,都取的是删除后这些数组中有效的值,那些无用的后面还连接着的值就不要了,比如,我们用暴力解法删除123234里的2删除后的顺序就是133444这里的后面的两个4是不算的,所以实际上有效的数组是1334,所以题目中说让我们返回新数组的长度,并且不再考虑新的长度后面的数据,在这里这数据就指的是44
2.左右指针法
//左右指针法:该方法的思路是:我们定义左右两个指针让我们将要删除的值全都移动到数组的右边,剩下的值就都在左边了,此时就只需要返回左侧值的末尾就行了,这个末尾就是我们数组的新长度
public int removeElement(int[] nums,int val) {
int left =0;
int right = nums.length - 1;
while(left <= right){
while(left <= right && nums[left]!=val){
left++;//当左侧的值不等于val时就++,直到找到的值等于val的时候停下来
}
while (left <= right && nums[right]==val){
right--;//当右侧的值等于val时就--,直到找到的值不等于val的时候停下来
}
if(left < right){//这一步判断也是很多人会直接写一个 nums[left++] = nums[right--];
//而不去判断是否left < right 这是错误的,在下面的画图中我们会详细讲到
nums[left++] = nums[right--];//这一步就显得很高大上了,我们要学会去用这种写法,另外你还可以采用创建临时变量的方式
//来交换这两个值,但是那样没必要,因为我们此时只需要保留那个有用的值就行了,所以我们可以采用这种方式直接赋值
}
}
return left;//这一步也很巧妙,需要好好体悟
}//这种方法在力扣上能通过
3.双指针法
public int removeElement(int [] nums, int val) {
int slow = 0;
for (int fast = 0; fast < nums.length; fast++) {
if (val != nums[fast]) {//这里我们判断:只要数组里的元素不等于val就进去
nums[slow++] = nums[fast];//这里要好好模仿,使你的代码提升一个档次
}
}
return slow;
}//上面的代码是不是看了很懵,不过没关系,下面有详细的画图解释
//这种方法在力扣上也能正常运行
到这里就结束了,感谢您的阅读