力扣网编程题:移除元素(简单)

一. 简介

本文记录一下力扣网上涉及数组的问题:移除元素。

二. 力扣网编程题:移除元素(简单)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。
假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:
更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
返回 k。

示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2,_,_]
解释:你的函数函数应该返回 k = 2, 并且 nums 中的前两个元素均为 2。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3,_,_,_]
解释:你的函数应该返回 k = 5,并且 nums 中的前五个元素为 0,0,1,3,4。
注意这五个元素可以任意顺序返回。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

提示:
    0 <= nums.length <= 100
    0 <= nums[i] <= 50
    0 <= val <= 100

题目分析:

题目中提到 "原地"操作 指的是在不额外申请内存空间(或仅使用常数级额外空间)的前提下,直接修改原始数据结构的内容。

也就是说不能额外使用空间,在原有数组进行移动;可以使用双指针进行处理,有两种思路:

第一种思路是双指针从前往后遍历;

第二种思路是双指针,一个指向数组首部,一个指针指向数组尾部;

解题思路一:(双指针 / 从前往后)

1. 定义两个指针 left 和 right,使用 left指针指向新数组的当前位置;

2. 使用 right指针遍历原数组,进行判断;

3. 当 nums[right] != val时,将 nums[right] 赋值给 nums[left];

循环退出后,新数组长度即为left。

C语言实现如下:


//双指针/从前往后
int removeElement(int* nums, int numsSize, int val) {
    int left = 0;
    int right = 0;

    while(right < numsSize) {
        if(nums[right] != val){
            nums[left] = nums[right];
            left++;
        }
        right++;
    }

    return left;
}

可以看到,这里没有申请额外的空间,在原来数组上进行的移动。

解题思路二:(双指针/从数组首尾同时开始)

1. 定义左右指针Left和 right:

left指针:始终指向新数组的下一个可写入位置。

right指针:指向数组末尾,用于提供可替换的有效元素(即 != val的元素);

2. 遍历数组,遍历当前元素:

当 nums[left] == val时:

寻找数组末尾可以替换的元素;检查右指针所指元素是否等于val;

     若 nums[right] != val:将其值赋给 nums[left],并将 left 右移一位(因为该位置已被有效元素填充)。
    无论是否找到有效元素,都将 right 左移一位(缩小有效范围)。


当前元素不等于 val 时(nums[left] != val):
    直接将 left 右移一位,继续检查下一个元素。

3. 当left > right时,left就是最新的数组长度;
当 left > right 时循环终止。此时有两种可能:
    right 指针向左越过了 left 指针(即 right = left - 1)
    left 指针向右越过了 right 指针(即 left = right + 1)
无论哪种情况,最终状态都是 left 指向第一个未被处理的位置,而 right 指向最后一个被处理的有效元素的前一个位置。

C语言实现如下:


//双指针/从数组首尾开始处理
int removeElement(int* nums, int numsSize, int val) {
    int left = 0;
    int right = numsSize-1;

    while(left <= right) {
        if(nums[left] == val) {
            if(nums[right] != val) {
                nums[left] = nums[right];
                left++;
            }
            right--;
        }
        else { //nums[left] != val
            left++;
        }
    }

    return left;
}

你可能感兴趣的:(逻辑编程题,leetcode,算法,数据结构)