leetCode-1两数之和问题

336 阅读2分钟

函数执行时间计算工具

计算代码块执行时间使用CFAbsoluteTimeGetCurrent单位是

/* absolute time is the time interval since the reference date */
/* the reference date (epoch) is 00:00:00 1 January 2001. */
/* 获取的是从2001年1月1号00:00:00到现在经过的秒数*/

public func CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime


// 用法
let startTime = CFAbsoluteTimeGetCurrent()
//要执行的代码
let endTime = CFAbsoluteTimeGetCurrent()
let duration = String.init(format: "%.3f", (endTime - startTime)*1000) + "毫秒"

本文使用swift语言实现算法

题目

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

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

暴力破解法

func twoNums(nums:[Int],target:Int) -> [Int] {
    for i in 0...nums.count-2{
        for j in i+1...nums.count-1{
            if nums[i]+nums[j] == target {
                return [i,j]
            }
        }
    }
    return []
}
let startTime = CFAbsoluteTimeGetCurrent()
let result = twoNums(nums: [2,9,7,11,13],target:9)
let endTime = CFAbsoluteTimeGetCurrent()

let duration = String.init(format: "%.3f", (endTime - startTime)*1000) + "毫秒"
print(duration,result)

执行结果

0.754毫秒 [0, 2]

遍历数组并判断当前值和之后所有值相加是否等于target的值,需要两层循环

  • 时间复杂度为O(n²)
  • 空间复杂度O(1) 这种方式比较好理解,扩展到三个数之和的问题也是如此,再加一层循环就好了🐶,但是时间复杂度稍高

两遍哈希

什么样的数据结构查找起来最快?是有序数组吗?好像哈希表更快一些

  • 二分查找时间复杂度O(logn)
  • 哈希表时间复杂度O(1) 我们尝试借助哈希表来降低时间复杂度
func twoNums2(nums:[Int],target:Int) -> [Int] {
    var hMap:[Int:Int] = [:];
    for i in 0...nums.count-1{
        hMap[target-nums[i]] = i
    }
    for i in 0...nums.count-1 {
        if hMap.keys.contains(nums[i]) {
            return [i,hMap[nums[i]]!]
        }
    }
    return []
}

执行结果

2.598毫秒 [0, 2]

第一遍循环将nums中的值以[target-nums[i]:i]的形式存储在一个哈嘻表中

  • 时间复杂度O(n)
  • 空间复杂度O(n) 第二次循环就成了判断数组中是否存在某个值的问题
  • 时间复杂度O(n),哈希查找时间复杂度O(1)
  • 没有空间复杂度 所以总的时间复杂度O(2n+1)=O(n),空间复杂度O(n)

一遍哈希

这是第二种解法两遍哈希的改进版本,可以在一次循环中完成

func twoNums3(nums:[Int],target:Int) -> [Int] {
    var hMap:[Int:Int] = [:];
    for i in 0...nums.count-1{
        if hMap.keys.contains(nums[i]) {
            return [i,hMap[nums[i]]!]
        }
        hMap[target-nums[i]] = i
    }
    return []
}

执行结果

1.412毫秒 [2, 0]
  • 时间复杂度O(n)
  • 空间复杂度O(n)

参考文章

# Leetcode题:两数之和

# 漫画算法题:两数之和与三数之和