LeetCode 27 移除元素
给定一个数组 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。
注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。
双指针
算法思路
当 nums[j] 与给定的值相等时,递增 j 以跳过该元素。只要 nums[j]不等于val,我们就复制 nums[j]到 nums[i] 并同时递增两个索引。重复这一过程,直到 j 到达数组的末尾,该数组的新长度为 i。
public int removeElement(int[] nums, int val) {
int i = 0;
for (int j = 0; j < nums.length; j++) {
if (nums[j] != val) {
nums[i] = nums[j];
i++;
}
}
return i;
}
双指针 —— 当要删除的元素很少时
当我们遇到 nums[i] =val 时,我们可以将当前元素与最后一个元素进行交换,并释放最后一个元素。这实际上使数组的大小减少了 1。元素的顺序可以进行改变,只考虑需要移除的元素。
public int removeElement(int[] nums, int val) {
int i = 0;
int n = nums.length;
while (i < n) {
if (nums[i] == val) {
nums[i] = nums[n - 1];
// reduce array size by one
n--;
} else {
i++;
}
}
return n;
}
相关例题
LeetCode 88 合并两个有序数组
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
/*双指针法
* 最直接的算法实现是将指针p1 置为 nums1的开头, p2为 nums2的开头,在每一步将最小值放入输出数组中。
由于 nums1 是用于输出的数组,需要将nums1中的前m个元素放在其他地方,也就需要 O(m)O(m) 的空间复杂度。
*/
public void Merge1(int[] nums1,int m,int[] nums2,int n){
int[] nums1_copy = new int[m];//定义一个长度为nums1的copy数组
System.arraycopy(nums1,0,nums1_copy,0,m);
//设置三个指针
int p1 = 0;
int p2 = 0;
int p = 0; //合并指针
/*分为三种情况 p1 and p2 在范围内
* p1 在范围内
* p2 在范围内*/
while((p1<m) && (p2<n)){
nums1[p++] = (nums1_copy[p1] < nums2[p2] ? nums1_copy[p1++] : nums2[p2++]);//比较一次指针增加
}
if(p1<m){
System.arraycopy(nums1_copy,p1,nums1,p1+p2,m+n-p1-p2);
}
if (p2<n){
System.arraycopy(nums2,p2,nums1,p1+p2,m+n-p1-p2);
}
}