【发布时间】:2020-04-19 06:22:38
【问题描述】:
问题陈述
我将尝试通过一个场景来详细说明这个案例。让我们以这个问题为例。
问题链接:https://leetcode.com/problems/remove-element/
给定一个数组
nums和一个值target,删除所有实例 该值就地并返回新的长度。不要为另一个数组分配额外的空间,您必须通过 O(1) 额外内存就地修改输入数组来做到这一点。
示例:给定
nums = [0,1,2,2,3,0,4,2],target = 2;output = 5(不等于目标的元素数)并将数组修改为[0,1,3,0,4]元素的顺序可以改变。你离开什么都没关系 超出新长度。
我的方法
步骤 1:识别与给定目标相等的所有元素,并将它们移动到数组的右侧,同时保持一个计数器。
第 2 步:从右侧删除所有元素。
Step-3:return (n - counter),其中 n 是数组长度,counter 是等于 target 的元素数。
下面是相同的实现:
object RemoveElement {
// Link to question: https://leetcode.com/problems/remove-element/
def main(args: Array[String]): Unit = {
var nums = Array(3,2,2,3)
val target = 3
val result = removeElement(nums, target)
// nums = nums.dropRight(_.equals(target)) // POINT 1
println(s"Result: ${result}, Modified Array: [${nums.mkString(", ")}]")
}
def removeElement(nums: Array[Int], target: Int): Int = {
val n = nums.length
var left, counter = 0
var right = n - 1
while(left < right){
if(nums(left) != target){
left += 1
}
else {
// Find position of the elements which is not equal to target
if(nums(right) == target){
counter += 1
right -= 1
}
else{
// Swap the elements
counter += 1
val temp = nums(left)
nums(left) = nums(right)
nums(right) = temp
left += 1
right -= 1
}
}
}
// nums.dropWhile(_.equals(target)) // POINT 2
// nums = nums.dropRight(_.equals(target)) // POINT 3
return (n - counter)
}
}
要点 - 1:绝对有意义,因为数组 nums 在 main 方法的范围内,因此,该语句将作为魅力。
POINT - 2:这些行对数组nums 没有影响。
POINT - 3:给出错误。我知道输入参数(数组nums)的类型为val(即通过引用传递,因此在removeElement 方法的范围内是不可变的)。
如果我可以选择创建一个新数组,那不会有任何问题。但是,如果我需要通过向调用方法添加/删除元素(如在这个问题中)来返回修改后的数组,我该如何在 Scala 中实现呢?
为了使案例更通用,我们可以通过什么方式修改 Scala 方法中的输入集合(作为参数传递)?
P.S.:如果我不从输入数组本身中删除元素,LeetCode 会导致我的提交失败,并显示以下消息:
【问题讨论】:
-
这里的东西太多了。首先,这些问题非常紧迫,它们可能对学习 Python 、Java 或 C/C++ 等语言有好处,但对 则不然Scala 是一种更具声明性的语言,即使 Scala 允许您在需要(例如在性能很重要时) 时使用命令式,这并不常见,因此,如果您要学习一门语言,最好用地道的方式学习它。
-
第二,我认为这个问题有点误导,AFAIK Array 是一个固定大小的保留内存量,你不能真正从中删除元素,你可以用零或
null填充多余的空格。但他们必须留在那里。这不仅适用于 Scala,而且适用于任何 JVM 语言。此外,我希望任何母语 (例如 C/C++ 或 Python) 都可以使用相同的方法,但使用malloc可能会有一些技巧修剪记忆。 -
真的!但是 Scala 提供了许多功能性能力并在内部为我们处理事情。
drop/dropRight是为我们做脏活的方法之一。如果必须的话,我只想弄清楚如何在上述问题中描述的情况下进行处理。 -
collections 库中的几乎所有方法都返回修改后的副本,而不是修改原始集合。一些 mutable 集合提供就地修改方法,但这些通常保留用于特殊情况。在 Array 的情况下,这样的
dropInPlace不存在(可能是我在第二条评论中所说的)。最后,即使性能很重要,公开一个修改其输入的公共方法也是很奇怪的。
标签: arrays scala pass-by-reference