题目:
给定一个数组和一个值,使用就地算法将数组中所有等于这个值的元素删除,并返回新数组的长度。
元素的顺序可以更改。你不用去关心大于当前数组长度的空间里面存储的值。
例1: 给定 nums = [3,2,2,3], val = 3,函数应该返回新的长度 2, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。
例2:给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。 你不需要考虑数组中超出新长度后面的元素。
思路:
思路1:暴力循环移位求解。
思路2:根据快速排序的思想,从两端向中间遍历,将前端等于val的元素和后端不等于val的元素互换。
代码:
package com.company;
public class TestNo16 {
public static void main(String[] args) {
TestNo16 t = new TestNo16();
int[] a = {2,3,3,2};
int[] a1 = {1,4,4,5,6};
//System.out.println(t.removeElement(a,2));
System.out.println(t.removeElement(a1,4));
}
public int removeElement(int[] A, int elem) {
int len = A.length;
if(len == 0)
return 0;
int low = 0,high = len-1;
int temp = 0; //举例子:列出第一层循环的过程
while (low <= high){// A = {1,4,4,5,6}, low = 0, high = 4,elem = 4
while (low <= high && A[low]!= elem) // A[0] = 1,因为!=4, 所以 low++ ,low = 1
low++;
while (low <= high && A[high] == elem){ // 此时low = 1,high = 4,满足条件,A[high] = 6 != 4, 不满足条件
high--;
len--;
}
if(low <= high){//此时low=2,high= 4,满足条件
temp = A[high]; // temp = 6;
A[high] = A[low]; // A[low] = 4, A[high] = 4;
A[low] = temp; // A[low] = 6; 此时A = [1,6,4,5,4]
high--; //high = 3;
low++; // low = 2;
len--; //len = 4;
}
}
return len;
}
}
思路3:在原数组里面进行修改,利用双指针进行遍历,i是从左到右进行遍历,j是从右向左进行遍历。当A[i] = elem时,将A[j]的值代替A[i]的值,并且i++,无需将A[i]的值代替A[j]的值。
代码:
扫描二维码关注公众号,回复:
9197601 查看本文章
package com.company;
public class TestNo16_1 {
public static void main(String[] args) {
TestNo16_1 t = new TestNo16_1();
int[] a = {1,3,3,4,6};
System.out.println(t.removeElement(a,3));
}
public int removeElement(int[] A, int elem){
int i = 0,j = A.length-1;// i是左指针,j是右指针
while (i <= j){
if(A[i] == elem){
A[i] = A[j]; //得到索引j的值,无需把索引j的值改为索引i的值。
j--;
}else{
i++;
}
}
return j+1;
}
}