问题1:如何删除数组中重复的元素只保留一个(双指针思想)
示例
输入:arr=[1,1,1,2,2,3,4,4,5,5,5,5,6,7,8,8,9,9,10]
输出:arr=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0]
思路:
1.定义两个整型变量slow和fast用于表示索引,初始值都为0。
2.首先令fast=fast+1,判断arr[slow]与arr[fast]是否相等,如果相等则令fast=fast+1,如果不相等则令slow=slow+1,arr[slow]=arr[fast],然后从以上fast=fast+1开始重复操作,直到fast遍历完arr,最后将arr从slow+1索引处到结尾的所有元素赋值为0.
图解如下:
具体代码如下:
public class Test {
public static void main(String[] args) {
int[] arr = {1,1,1,2,2,3,4,4,5,5,5,5,6,7,8,8,9,9,10};
int slow = 0;
int fast = 0;
while(fast<arr.length-1) {
fast++;
if(arr[slow] != arr[fast]) {
slow++;
arr[slow] = arr[fast];
}
}
for(int i=slow+1;i<arr.length;i++) {
arr[i]=0;
}
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}
问题2:原地移除数组中数值等于val的所有元素并返回数组中元素的个数
要求:原地移除所有数值等于val的元素,并返回移除后数组的新长度。不使用额外的数组空间,元素的顺序可以改变,不需要考虑数组中超出新长度后面的元素
例子1:
输入:nums = [0,1,2,2,3,0,4,2],val = 2
输出:5,nums=[0,1,3,0,4]
方法1:快慢双指针
思路:先定义两个变量slow=0,fast=0代表索引,利用fast<nums.length开始遍历数组。nums[fast] != val时,令nums[slow] = nums[fast]并且slow=slow+1.遍历结束后返回的slow即为数组新长度,即是从slow的前半部分有效,后半部分是无效部分。
图解如下:
具体代码如下:
public class Test {
public static void main(String[] args) {
int[] nums = {0,1,2,2,3,0,4,2};
int val = 2;
int slow = 0;
int fast = 0;
for(fast=0;fast<nums.length;fast++) {
if(nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
}
System.out.println("还剩元素个数为:"+slow);
}
}
方法2:对撞双指针
思路:从数组的右侧找到不是val值来顶替左侧是val的值。
图解如下:
具体代码如下:
public class Test {
public static void main(String[] args) {
int[] nums = {0,1,2,2,3,0,4,2};
int val = 2;
int slow = 0;
int fast = nums.length-1;
for(;slow<=fast;) {
if(nums[slow] == val && nums[fast] != val) {
int temp = nums[slow];
nums[slow] = nums[fast];
nums[fast] = temp;
}
if(nums[slow] != val) {
slow++;
}
if(nums[fast] == val) {
fast--;
}
}
System.out.println("剩余元素个数"+slow);
}
}