面试经典算法系列之数组/字符串3 -- 移除元素

面试经典算法题35-移除元素

LeetCode.27
公众号:阿Q技术站

问题描述

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

思路

方法一 遍历 - 去除匹配项
  1. 初始化一个变量 count 用于计数非给定值的元素。
  2. 遍历数组,当遇到非给定值的元素时,将其移到数组的前面,并增加 count
  3. 修改数组的长度为 count,即可移除给定值的元素。
方法二 双指针
  1. 初始化两个指针:我们使用两个指针 leftright,初始时都指向数组的开头。
  2. 遍历数组:遍历数组,当 nums[right] 等于给定值 val 时,右指针 right 向右移动一位;否则,将 nums[right] 的值赋给 nums[left],并同时将 leftright 向右移动一位。
  3. 返回新长度:遍历结束后,left 指向的位置即为新数组的长度。
方法三 双指针 - 交换移除
  1. 初始化两个指针 leftright,初始时 left 指向数组开头,right 指向数组末尾。
  2. nums[left] 等于给定值 val 时,将 nums[left]nums[right] 交换,并将 right 向左移动一位。
  3. 如果交换后的 nums[left] 仍然等于给定值 val,则继续交换直到 nums[left] 不等于 val
  4. left 向右移动一位,重复步骤 2 和 3,直到 left 大于等于 right
  5. 返回新数组的长度,即 left 的值。

图解

方法一

流程图

方法二

参考代码

C++
方法一
#include <iostream>
#include <vector>

using namespace std;

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int i = 0; // 初始化指针 i,指向数组的第一个位置
        for (int j = 0; j < nums.size(); ++j) { // 遍历数组,j指向当前处理的元素
            if (nums[j] != val) { // 如果当前元素不等于给定值
                nums[i] = nums[j]; // 将当前元素移动到指针 i 的位置,并同时移动指针 i
                ++i; // 指针 i 向后移动
            }
        }
        return i; // 返回新数组的长度,即指针 i 的值
    }
};

int main() {
    vector<int> nums = {3, 2, 2, 3}; // 输入数组
    int val = 3; // 给定值
    Solution solution;
    int result = solution.removeElement(nums, val); // 移除给定值并返回新数组长度
    cout << "新数组长度:" << result << endl; // 输出结果
    return 0;
}
方法二
#include <iostream>
#include <vector>

using namespace std;

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int left = 0, right = 0; // 初始化左右指针
        while (right < nums.size()) { // 遍历数组
            if (nums[right] != val) { // 如果当前元素不等于给定值
                nums[left] = nums[right]; // 将当前元素赋值给左指针指向的位置
                left++; // 左指针向右移动一位
            }
            right++; // 右指针向右移动一位
        }
        return left; // 返回新数组的长度
    }
};

int main() {
    vector<int> nums = {3, 2, 2, 3}; // 输入数组
    int val = 3; // 给定值
    Solution solution;
    int result = solution.removeElement(nums, val); // 移除元素
    cout << "新数组长度:" << result << endl; // 输出结果

    return 0;
}
方法三
#include <iostream>
#include <vector>

using namespace std;

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int left = 0, right = nums.size(); // 初始化左右指针,left指向数组开头,right指向数组末尾的下一个位置
        while (left < right) { // 循环直到左指针大于等于右指针
            if (nums[left] == val) { // 如果左指针指向的值等于给定值
                nums[left] = nums[right - 1]; // 将左指针指向的值与右指针前一个位置的值交换
                right--; // 缩小数组长度
            } else { // 如果左指针指向的值不等于给定值
                left++; // 左指针右移
            }
        }
        return left; // 返回新数组的长度,即左指针的值
    }
};

int main() {
    vector<int> nums = {3, 2, 2, 3}; // 输入数组
    int val = 3; // 给定值
    Solution solution;
    int result = solution.removeElement(nums, val); // 移除给定值并返回新数组长度
    cout << "新数组长度:" << result << endl; // 输出结果
    return 0;
}
Java
class Solution {
    public int removeElement(int[] nums, int val) {
        int i = 0; // 初始化指针 i,指向数组的第一个位置
        for (int j = 0; j < nums.length; ++j) { // 遍历数组,j指向当前处理的元素
            if (nums[j] != val) { // 如果当前元素不等于给定值
                nums[i] = nums[j]; // 将当前元素移动到指针 i 的位置,并同时移动指针 i
                ++i; // 指针 i 向后移动
            }
        }
        return i; // 返回新数组的长度,即指针 i 的值
    }
}

public class Main {
    public static void main(String[] args) {
        int[] nums = {3, 2, 2, 3}; // 输入数组
        int val = 3; // 给定值
        Solution solution = new Solution();
        int result = solution.removeElement(nums, val); // 移除给定值并返回新数组长度
        System.out.println("新数组长度:" + result); // 输出结果
    }
}
Python
from typing import List

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        i = 0  # 初始化指针 i,指向数组的第一个位置
        for j in range(len(nums)):  # 遍历数组,j指向当前处理的元素
            if nums[j] != val:  # 如果当前元素不等于给定值
                nums[i] = nums[j]  # 将当前元素移动到指针 i 的位置,并同时移动指针 i
                i += 1  # 指针 i 向后移动
        return i  # 返回新数组的长度,即指针 i 的值

# 测试代码
nums = [3, 2, 2, 3]  # 输入数组
val = 3  # 给定值
solution = Solution()
result = solution.removeElement(nums, val)  # 移除给定值并返回新数组长度
print("新数组长度:", result)  # 输出结果

相关推荐

  1. 面试经典 150 题 ---- 元素

    2024-05-12 08:20:07       59 阅读
  2. 面试经典150题——元素

    2024-05-12 08:20:07       34 阅读
  3. 算法-数组元素

    2024-05-12 08:20:07       37 阅读
  4. 面试算法-109-元素

    2024-05-12 08:20:07       37 阅读
  5. 【力扣经典面试题】27. 元素

    2024-05-12 08:20:07       64 阅读
  6. LeetCode 面试经典150题 27.元素

    2024-05-12 08:20:07       41 阅读
  7. 【leetcode面试经典150题】2.元素(C++)

    2024-05-12 08:20:07       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-12 08:20:07       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-12 08:20:07       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-12 08:20:07       87 阅读
  4. Python语言-面向对象

    2024-05-12 08:20:07       96 阅读

热门阅读

  1. HarmonyOS应用开发者高级认证 试题+答案

    2024-05-12 08:20:07       30 阅读
  2. 1-k8s常见注意事项

    2024-05-12 08:20:07       27 阅读
  3. KubeKey 部署 K8s v1.28.8 实战

    2024-05-12 08:20:07       29 阅读
  4. 从零开始精通RTSP之传输AAC音频流

    2024-05-12 08:20:07       34 阅读
  5. 【GitHub】将本地VueCLI项目关联到GitHub远程仓库

    2024-05-12 08:20:07       31 阅读
  6. Vue3实战笔记(07)— Axios进阶与提高

    2024-05-12 08:20:07       32 阅读
  7. Flink面试整理-Flink的监控和日志收集

    2024-05-12 08:20:07       35 阅读
  8. Spring STOMP-开启STOMP

    2024-05-12 08:20:07       36 阅读