给定一个数组和一个值,使用就地算法将数组中所有等于这个值的元素删除,并返回新数组的长度。
元素的顺序可以更改。你不用去关心大于当前数组长度的空间里面存储的值
/**
* 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;
}
}