27. 移除元素
要求:
给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
难点:
数组存储是连续的,先调用循环找出数组中和val相同的元素,然后将这个元素删除,调用伪指针循环,将后面的所有元素都往前移。
注意,大循环的 i 伪指针,是从0循环到n,当删除数据后,n--,i--。
class Solution {
public int removeElement(int[] nums, int val) {
int n = nums.length;
for(int i=0; i<n; i++){
if(nums[i] == val){
for(int j=i+1; j<n; j++)
nums[j-1] = nums[j];
i--;
n--;
}
}
return n;
}
}
代码优化:
上面方法复杂之处,在于删一个元素就要遍历后面所有元素往前移,将删除改为赋值操作,这样数组元素仍然连续。
快慢指针,快慢指针都从0开始,快指针先去寻找不等于val的数组元素,这一部分的数组元素是需要保存在数组中作为输出结果的。当快指针找到一个目标,覆盖给慢指针,慢指针才开始继续往前走,慢指针走了几步,则最终输出的数组就有几个元素。
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for(int fast=0; fast<nums.length; fast++){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
}
26. 删除有序数组中的重复项
要求:
给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
返回 k 。
错误代码:
思路是27题的双重循环,大体一样,但是if 判断的条件不同,数组是递增序列要求将数组重复数据删掉,换种说法就是后一个数据元素不能小于或者等于前一个数组。
在if 判断条件中,在比较数组元素时,会导致最后一个数组元素没办法循环到。
class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
for(int i=0; i<n; i++){
if(nums[i] >= nums[i+1]){
for(int j=i+1; j<n; j++)
nums[j-1] = nums[j];
i--;
n--;
}
}
return n;
}
}
代码修改:
先讨论,第0个数据元素,它必定不会重复。将循环从1开始,方便第 i 个元素和第 i-1 个进行比较,这样数组中下标不会溢出。
class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
if(n == 0) return 0;
for(int i=1; i<n; i++){
if(nums[i] == nums[i-1]){
for(int j=i+1; j<n; j++)
nums[j-1] = nums[j];
i--;
n--;
}
}
return n;
}
}
代码优化:
仍然使用快慢指针,fast 循环可以用 for 也可以用 while。
class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
if(n == 0)
return 0;
int slow = 1, fast = 1;
while(fast < n){
if(nums[fast] != nums[slow-1]){
/*判断条件不能这么写,因为nums[fast]要和前一项确定的数据比较nums[fast] != nums[fast-1],而fast-1 还是有条件下不确定的,比如说允许数组重复2个,重复三个删掉第三个,是80题,本题的变式*/
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
}