算法面試題01 - 兩數之和

實現一個算法,在一個無序整型數組中,找到兩個數使其和為一個給定的值。請給出算法實現的代碼,并分析算法時間和空間復雜度。

【示例】
給定數組numbers = [3, 7, 2, 5, 9],目標值sum = 9
因為numbers[1] + numbers[2] = 7 + 2 = 9
返回[1,2]

【要求】
輸入一個無序數組,通過算法可以找到兩數之和等于目標值的兩元素的索引。

答案:

let numbers = [3, 7, 2, 5, 9]
print(twoSum(numbers, 9))

func twoSum(_ nums: [Int], _ target: Int) -> [Int] {

    var dict = [Int:Int]()

    for (index, num) in nums.enumerated() {
        let other = target - num
        if let storedIndex = dict[other] {
            return [storedIndex, index]
        } else {
            dict[num] = index
        }
    }

    return []
}

這個算法首先使用一個字典保存每個元素和其索引。然后遍歷數組,并查找每個元素所對應的補數是否存在于字典中。
時間復雜度為 O(n),其中 n 為數組長度。算法只需要遍歷一次數組,并在字典中查找操作,所以時間復雜度為線性。
空間復雜度為 O(n),因為使用了一個字典存放了數組中的每個元素。
所以這個算法的時間和空間復雜度較優,總體來說效率較高。這是一種常見的兩數之和問題的解法。

知識點詳解:

無序整型數組指的是數組中的元素可以是任意順序,不是排序后的順序。
例如:[3, 7, 2, 5, 9]
這就是一個無序整型數組,數組中的整數元素并不是按照大小排序的。
如果數組是:[2, 3, 5, 7, 9]
則這是一個有序數組,元素是按照從小到大的順序排列的。

算法思路

  1. 定義一個字典dict來存放元素和索引
  2. 使用enumerated()遍歷數組,同時獲取元素和索引
  3. 定義other變量,來計算當前元素的補數(target值減去當前元素)
  4. 在字典中查找other是否存在:
    • 如果存在,表示找到了兩數之和,直接返回兩個元素的索引
    • 如果不存在,則將當前元素和索引添加到字典中
  5. 遍歷完成如果未找到,返回空數組
  6. 時間復雜度為O(n),空間復雜度為O(n)
    這種利用字典保存元素和索引的方法,可以快速查找補數是否存在,從而得出兩數之和的結果,是一個常用的算法

算法執行過程:

  1. dict = {}
  2. num = 3,dict[3] = 0
  3. num = 7,dict[7] = 1
  4. num = 2,目標值9與當前num的差值是7,7已在dict中,返回[dict[7] , index],即返回[1, 2]
  5. 兩數之和為7 + 2 = 9,索引分別為1和2,返回[1, 2]

代碼釋義:

func twoSum(_ nums: [Int], _ target: Int) -> [Int]
  • nums: 輸入的整數數組,用于查找兩數之和
  • target: 查找的目標和的值
  • 返回值:[Int]: 返回一個整數數組,包含兩數之和的兩個元素在原數組中的索引

也就是說:

  • 輸入:一個整數數組nums,和一個目標值target
  • 輸出:一個整數數組,包含兩個元素在nums數組中的索引,這兩個元素相加等于target

題外話

如果題目中的無序數組換成有序數組,該如何優化呢?

對于有序數組,可以利用二分查找算法來降低時間復雜度。
具體思路是:

  1. 給定一個有序數組 nums 和目標值 target
  2. 對數組進行二分查找,找到一個數 num
  3. 計算目標值與 num 的差值 diff = target - num
  4. 再在數組中二分查找 diff
  5. 如果找到diff,返回 num 和 diff 的下標即可
  6. 如果未找到,移動 num 的查找范圍,重復步驟2-5

該算法的時間復雜度可以降低到 O(logn),比線性查找更快。

參考代碼:

func twoSum2(_ nums: [Int], _ target: Int) -> [Int] {

    for i in 0..<nums.count {
        let complement = target - nums[i]
        if let j = binarySearch(nums, complement, i+1, nums.count-1) {
            return [i, j]
        }
    }
    
    return []
}

func binarySearch(_ nums: [Int], _ target: Int, _ left: Int, _ right: Int) -> Int? {

    if left > right {
        return nil
    }
    
    let mid = (left + right) / 2
    if nums[mid] == target {
        return mid
    } else if nums[mid] < target {
        return binarySearch(nums, target, mid+1, right)
    } else {
        return binarySearch(nums, target, left, mid-1)
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容