给定一个数组和一个值,使用就地算法将数组中所有等于这个值的元素删除,并返回新数组的长度。
元素的顺序可以更改。你不用去关心大于当前数组长度的空间里面存储的值
/**
* 27. Remove Element
* 移除元素
* 给定一个数组 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。
* 注意这五个元素可为任意顺序。
* 你不需要考虑数组中超出新长度后面的元素。
*
* @author shijiacheng
*/
public class Solution {
/**
* 使用两个游标i,j,遍历数组,如果碰到了value,使用j记录位置,同时递增i,
* 直到下一个非value出现,将此时i对应的值复制到j的位置上,增加j,重复上述
* 过程直到遍历结束。这时候j就是新的数组。比如数组为1,2,2,3,2,4,删除
* 2,首先初始化i和j为0,指向第一个位置,因为第一个元素为1,
* 所以A[0] = A[0],i和j都加1,而第二个元素为2,我们递增i,直到碰到3,
* 此时v[1] = v[3],也就是3,递增i和j,这时候下一个元素又是2,递增i,直
* 到碰到4,此时v[2] = v[5],也就是4,再次递增i和j,这时候数组已经遍历完
* 毕,结束。这时候j的值为3,刚好就是新的数组的长度。
*
*/
public int removeElement(int[] nums, int val) {
if (nums == null || nums.length == 0) {
return 0;
}
int j = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == val) {
continue;
}
nums[j] = nums[i];
j++;
}
return j;
}
public static void main(String[] args) {
Solution s = new Solution();
int[] nums = {0, 1, 2, 2, 3, 0, 4, 2};
int val = 2;
int length = s.removeElement(nums, val);
System.out.println(length);
}
}
//遍历数组,若数组元素A[i]与elem相等,则将数组最后一个元素替换A[i],数组长度减一(相当于取代A[i]位置) //由于最后一个数组元素也可能等于elem,因此需要再次判断当前位置(替换后的A[i]),执行i--操作,使循环回到当前遍历位置 public class Solution { public int removeElement(int[] A, int elem) { if(A == null || A.length == 0) return 0; int len = A.length; for(int i = 0; i < len; i++){ if(A[i] == elem){ A[i] = A[len-1]; len--; i--; } } return len; } }
/** *题目要求返回长度len,实际判题时,会从原数组中取(0,len-1)的元素作为新数组来与正确结果作比较 * 一开始真没明白这题要表达什么意思(逃 */ public class Solution { public int removeElement(int[] a, int elem) { if(a==null||a.length==0){ return 0; } int i=0,j=a.length-1; while(i<=j){ if(a[i]==elem){ a[i]=a[i]+a[j]; a[j]=a[i]-a[j]; a[i]=a[i]-a[j]; j--; }else{ i++; } } return j+1; } }
/* 思路:搬移 把要删除的元素放到数组末尾,返回前半部分数组的长度 使用双指针进行搬移比较方便。 */ class Solution { public: int removeElement(int A[], int n, int elem) { if(A == nullptr || n==0){ return 0; } //记录数组中等于elem的元素个数 int count = 0; for(int i=0;i<n;i++){ if(A[i]==elem){ count++; } } int left = 0; int right = n-1; while(left<right){ //左右指针都不满足 if(A[left]==elem && A[right]!=elem){ A[left] = A[right]; A[right] = elem; left++; right--; continue; } //左指针满足,说明右指针不满足 if(A[left]==elem){ right--; continue; } //右指针满足 if(A[right]!=elem){ left++; continue;; } //左右指针都不满足 left++; right--; } return n-count; } };
//这里按照调试的评判标准,输出的不为升序数组 int nail = A.length; //注意考虑length-1情况,所以nail不为length-1 if (A.length == 0) { return 0; } for (int index = 0; index < A.length; index++) { if (A[index] == elem) { while ((nail > index) && (A[--nail] == elem)) { //找到index位置后,nail前面的elem } A[index]=A[nail]; } } return nail; //nail是旧数组后面第一次被换成elem的位置,所以等于新数组的长度
public class Solution { public int removeElement(int[] A, int elem) { int count = 0; for(int i=0;i<A.length;i++){ if(A[i]!=elem){ A[count++] = A[i]; } } return count; } }
public int removeElement(int[] A, int elem) { int length=0; length=A.length; for(int i=0;i<length;i++){ if(A[i]==elem){ int j=length-1; while(j>=i){ if(A[j]!=elem){ A[i]=A[j]; length--; break; }else { length--; j--; } } } } return length; }
class Solution { public: int removeElement(int A[], int n, int elem) { int count=0; for (int i=0;i<n;i++){ if (A[i]==elem) count+=1; else A[i-count]=A[i]; } return n-count; } };
public class Solution { public int removeElement(int[] A, int elem) { if(A == null || A.length == 0){ return 0; } int length = A.length; //elem出现位置标记 int forElem = 0; //数组遍历标记 int forEach = 0; while(forEach < length){ //若出现删除值 且 此前未因出现删除值导致forElem和forEach步调不一 if(A[forEach] == elem){ //forElem记录当前将elem下标 forEach++; continue; } //步调不一且 forEach找到forElem后不为elem的元素 A[forElem++] = A[forEach++]; } return forElem; } }