[LeetCode] 448. Find All Numbers Disappeared in an Array(找出数组里的所有消失的数)
-
Difficulty: Easy
-
Related Topics: Array
-
Link: https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/
Description
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
给定一个整形数组,数组内的每个元素都在 \([1, n]\) 之间(n 为数组大小),一些元素出现了两次,其余元素只出现一次。
Find all the elements of [1, n] inclusive that do not appear in this array.
找出 \([1, n]\) 之内没有出现在数组中的元素。
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
你能不使用额外空间,并在 O(N) 时间复杂度内完成吗?返回的 list 不计入额外空间的计算。
Examples
Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]
Hint
-
This is a really easy problem if you decide to use additional memory. For those trying to write an initial solution using additional memory, think counters!
如果使用了额外空间,这题就真的很简单。针对这种方法,想一想计数器!
-
However, the trick really is to not use any additional space than what is already available to use. Sometimes, multiple passes over the input array help find the solution. However, there's an interesting piece of information in this problem that makes it easy to re-use the input array itself for the solution.
然而,这题的难点就在于不使用额外的空间。有时,对输入的数组进行多遍扫描有助于解答该问题。然而,题目中隐藏了一个很有意思的信息使得复用原有数组解答此题变得容易
-
The problem specifies that the numbers in the array will be in range [1, n] where n is the number of elements in the array. Can we use this information and modify the array in-place somehow to find what we need?
这题规定了数组中的元素都在 \([1, n]\) 之间(n 为数组大小)。我们能否利用这个信息对输入的数组进行一些修改来达成目的?
Solution
题目规定数组内的元素都在 \([1, n]\) 之间,数组的索引范围是 \([0, n-1]\)。根据题目的提示,结合前面的这两个范围,可以找到一个元素的修改方法:
-
对于数组内的每个元素
num
,取其绝对值然后减 1(为什么要取绝对值,下面会说) -
以第 1 步得到的值为下标,把数组中对应下标的元素置为其相反数(其它改动应该也行,不过相反数是最直观的)
知道为啥要取绝对值了吗?这个元素可能已经被标记过了,所以需要取其绝对值
-
数组中所有正数对应的下标 +1 即为所求
代码如下
import kotlin.math.abs
class Solution {
fun findDisappearedNumbers(nums: IntArray): List<Int> {
val result = arrayListOf<Int>()
for (i in nums.indices) {
val index = abs(nums[i]) - 1
if (nums[index] > 0) {
nums[index] = -nums[index]
}
}
for (i in nums.indices) {
if (nums[i] > 0) {
result.add(i + 1)
}
}
return result
}
}