前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >算法养成记:移除元素

算法养成记:移除元素

作者头像
三哥
发布2020-03-26 17:10:08
3300
发布2020-03-26 17:10:08
举报
文章被收录于专栏:java工会java工会

呆萌程序员

算法养成记

LeetCode27

Remove Element

Given an array nums and a value val, remove all instances of that value in-place and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

Example 1:

Given nums = [3,2,2,3], val = 3, Your function should return length = 2, with the first two elements of nums being 2. It doesn't matter what you leave beyond the returned length.

Example 2:

Given nums = [0,1,2,2,3,0,4,2], val = 2, Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4. Note that the order of those five elements can be arbitrary. It doesn't matter what values are set beyond the returned length.

Clarification:

Confused why the returned value is an integer but your answer is an array?

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

Internally you can think of this:

// nums is passed in by reference. (i.e., without making a copy) int len = removeElement(nums, val); // any modification to nums in your function would be known by the caller. // using the length returned by your function, it prints the first len elements. for (int i = 0; i < len; i++) { print(nums[i]); }

中文意思就是:

给你一个数组 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 是以“引用”方式传递的。也就是说,不对实参作任何拷贝

int len = removeElement(nums, val);

// 在函数里修改输入数组对于调用者是可见的。

// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。

for (int i = 0; i < len; i++) {

print(nums[i]);

}

遍历一次数组是一定的

我们先考虑当nums[i]!=val的操作

题目不要求保持数组顺序,也就是说我们不用考虑移动的问题;

返回的结果也是只需要删除后的长度,所以只需要一个额外变量就行;

  1. 定义一个变量l,赋初值0,用于记录变化后的数组长度,也记录该数组尾部的位置;
  2. 从0开始遍历数组,当前数组的值nums[i]不等于需要剔除的值val时,就将nums[i]的值放到nums[l]的位置;如果nums[i]==val,就跳过;这样遍历到数组尾部时,l之前的数组就是剔除了val的新数组,l+1的长度就是新数组的长度;

遍历一次数组是一定的,用i来指遍历的数组下标,这次考虑当nums[i]==val的操作;

  1. 遍历数组,当前数组的值nums[i]等于需要剔除的值val时,该值是需要被替换掉的,此时我们可以将最后一个元素替换掉nums[i];
  2. 此时又会出现新的情况,最后一个元素可能等于val,可能不等于,所以需要重新判断。所以此时的i需要指回前一个元素,即i--,这样才能在下一次判断时,判定的是先前移动的最后一个元素的值;
  3. 由于将最后一个元素覆盖了nums[i],所以需要一个指针来指数组nums当前的尾部;所以l的初始值等于nums的长度;i<l时跳出循环;

上图的方法还有一种简洁一点的写法

在实际测试里

执行用时分别是:0ms,0ms,0ms

内存消耗分别是:37.9MB,37.9MB,37.9MB

对比一下移除有序数组中的重复元素?

数据结构和算法一直都是程序员面试重点。写好每一个方法,每一个接口,程序的效率也会越来越高。为了学习和巩固数据结构和算法,我们特别创作了《呆萌程序员--明明凯凯算法养成记》,每天更新一篇数据结构知识点或者刷一道LeetCode题目。算法都会在LeetCode上测试。当然答案不唯一,由于能力有限,实现方法不一定是最好的,也希望各位小伙伴一起来学习分享~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java工会 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档