在给定的整数列表(非负数字)中,确定列表中是否存在一对数字,以使它们的和等于指定的number
。
如果是,则以对形式从较小到较大返回它们的索引。
如果不是,请返回Pair (-1, -1)
。
fun findSumOfTwo(list: List<Int>, number: Int): Pair<Int, Int> {
for (item in list) {
for (digit in list - 1) {
if (item + digit == number) return Pair (list[item], list [digit])
}
}
return Pair (-1, -1)
}
我知道,除了我的代码无法正常工作之外,它还远远不够完美。而且我想从Kotlin语言的角度获得最惯用的解决方案。
答案 0 :(得分:3)
从字面上看,这是最常见的面试问题之一。
您当前的解决方案是时间复杂度为 O(N ^ 2)不好,但是,它的空间复杂度为 O(1),很好。
这是此方法的有效版本:
fun findSumOfTwo(arr: IntArray, targetSum: Int): Pair<Int, Int> {
if (arr.size < 2) return Pair(-1, -1)
var sum: Int
for (i in 0..arr.size - 2) {
for (j in i + 1..arr.size - 1) {
sum = arr[i] + arr[j]
if (sum == targetSum) {
if (arr[i] < arr[j]) {
return Pair(i, j)
}
return Pair(j, i)
}
}
}
return Pair(-1, -1)
}
在对类似于您的采访者的内容进行编码之后,很可能会要求您将时间复杂度优化为 O(N),(空间复杂度将需要增加至 O(N)< / strong>,但没关系,在大多数情况下,时间复杂度更为重要。
您可以使用 HashMap 通过一次通过:
fun findSumOfTwo(arr: IntArray, targetSum: Int): Pair<Int, Int> {
if (arr.size < 2) return Pair(-1, -1)
var map = HashMap<Int, Int>()
for (i in 0..arr.size - 1) {
var complement = targetSum - arr[i]
if (map.containsKey(complement)) {
var complementIndex = map.get(complement)!!
if (arr[i] < complement) {
return Pair(i, complementIndex)
}
return Pair(complementIndex, i)
}
map.put(arr[i], i)
}
return Pair(-1, -1)
}
注意:以上两个解决方案有两个假设:1)输入数组未排序。 2)如果输入数组中有一对以上有效对,则只返回一对有效就可以了。
答案 1 :(得分:1)
由于您只关心元素总和等于某个数字的一对索引,因此请使用forEachIndexed:
fun findSumOfTwo(list: List<Int>, number: Int): Pair<Int, Int> {
list.forEachIndexed { i1, e1 ->
list.forEachIndexed { i2, e2 ->
if(e1 + e2 == number) {
return i1 to i2
}
}
}
return Pair (-1, -1)
}
答案 2 :(得分:-1)
(我只是意识到这是无效的。因此,请跳过此解决方案:()这里有2条评论。
@media screen and (max-width: 1100px) {
.project-img {
display: block;
}
}
@media screen and (min-width: 1100px) {
.project-img {
width: 1100px;
display: inline;
}
}
和number = -2
。然后list = listOf(-1)
无法告诉我们这对输入Pair(-1, -1)
是否可用。另一件事是Kotlin带有null安全功能。我们可以将其返回为可空类型,在这种情况下为list
。如果我们的函数返回空值,则意味着我们没有明确寻找的对。Pair<Int, Int>?
随时进行讨论:)