Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,Because nums[0] + nums[1] = 2 + 7 = 9,return [0,1].
翻譯:
給定一個整數數組,返回兩個數的索引,使它們的和為一個目標值。
你可以假設每個輸入都只有一個答案,且一個元素只能使用一次。
Solution 1: 雙重循環
使用雙重循環,遍歷所有的情況,時間復雜度為 O(n^2) 。
在內層的循環中,索引從 i + 1
開始。
//Kotlin
class Solution {
fun twoSum(nums: IntArray, target: Int): IntArray {
for (i in 0..(nums.size - 1))
for (j in (i + 1)..(nums.size - 1))
if (nums[i] + nums[j] == target)
return intArrayOf(i, j)
return intArrayOf()
}
}
Solution 1.1:
對上面的代碼做一些小小的優化,在第一重循環中計算另一個數的值,可以減少加減計算次數。時間復雜度仍為 O(n^2) 。
//Kotlin
class Solution {
fun twoSum(nums: IntArray, target: Int): IntArray {
for (i in 0..(nums.size - 1)) {
val remain = target - nums[i]
for (j in (i + 1)..(nums.size - 1))
if (nums[j] == remain)
return intArrayOf(i, j)
}
return intArrayOf()
}
}
Solution 2:
另一種方法是對于已經排序的數組,從兩端向中間查找。
將數組從小到大排序,兩個索引分別為數組的第一個和最后一個元素,如果兩個值的大于目標值,第二個索引減1,反之第一個索引加1,直到兩個數的和為目標值。
//Kotlin
class Solution {
fun twoSum(nums: IntArray, target: Int): IntArray {
val ns = nums.mapIndexed { index, i -> Pair(index, i) }.sortedBy { p -> p.second }
var a = 0
var b = ns.size - 1
while (a != b) {
val sum = ns[a].second + ns[b].second
when {
sum == target -> return intArrayOf(ns[a].first, ns[b].first)
sum > target -> b--
sum < target -> a++
}
}
return intArrayOf()
}
}
Solution 3: 使用HashMap
遍歷數組,每個循環中,嘗試在HashMap中找第二個數的期望值,如果找到,返回結果,否則把當前數字放入HashMap,用于下次查找。時間復雜度為O(n)。
//Kotlin
class Solution {
fun twoSum(nums: IntArray, target: Int): IntArray {
val map = HashMap<Int, Int>()
nums.forEachIndexed { index, i ->
val a = map.get(target - i)
if (a != null) {
return intArrayOf(a, index)
}
map.put(i, index)
}
return intArrayOf()
}
}