每天一道LeetCode题——两数之和

前言

算法有多重要,不用多说。和之前学习设计模式一样,现在每天开始刷(bei)题(nue),并记录下答题思路和过程,希望这个系列能坚持吧。

题目

两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

解法

  • 暴力法
    最容易想到的思路就是双重遍历数组,直到在数组中找到两个数,它们的和等于目标值即可。
 fun twoSum(nums: IntArray, target: Int): IntArray {
        
        val result = IntArray(2)
        
        val length = nums.size
        
        for(i in 0 until length) {
            for(j in i+1 until length){
                if(nums[i] + nums[j] == target) {
                    result[0] = i
                    result[1] = j
                    break
                }
            }
        }
        return result
    }

但是这种解法时间复杂度太高了,达到了O(n^2)。想办法降低时间复杂度,减少多余重复的遍历才是重要的。

我们发现,当i从数组第0个遍历到数组最后一个的时候,j一直在重复遍历数组中的数字。这些遍历都是不必要的,重复的。因为只要一次遍历,我们就能知道数组中都有哪些数。

空间换时间,将数组中的数字和下标缓存到Map中。于是就有了改良之后的解法:Map缓存法。

  • Map缓存法

既然我们缓存了数组中的数字和下标,我们就不需要内层循环去寻找另一个加数。直接一次遍历,目标值与当前值的差值如果在Map中,说明之前的遍历有这个加数,直接返回下标即可。反之,则将当前值缓存到Map中,方便之后的遍历。

fun twoSum(nums: IntArray, target: Int): IntArray {

        val result = IntArray(2)

        val length = nums.size

        val cache = HashMap()//缓存数组中的值(key)和下标(value)

        for (i in 0 until length) {
            val current = nums[i]
            val diff = target - current
            if (cache.containsKey(diff)) {
                val key = cache[diff]
                if (key != null) {
                    result[0] = key
                    result[1] = i
                    break
                }

            } else {
                cache[current] = i
            }
        }
        return result
    }

你可能感兴趣的:(每天一道LeetCode题——两数之和)