LeetCode 之 JavaScript 解答第一題 —— 兩數之和(Two Sum)

不甘平凡的小鹿發表於2019-04-03

Time:2019/4/1
Title: Two Sum
Difficulty: simple
Author: 小鹿
公眾號:一個不甘平凡的碼農。

題目一:Two Sum

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.

問題:給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個陣列中同樣的元素。

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
複製程式碼

Solve:

▉ 法一:暴力破解法

演算法思路:用目標值減去陣列中的某一個數值,查詢差值是否在陣列中存在。

/**
 * 步驟:
 * 1)外迴圈:target 值要一一減去陣列中的元素,記錄差值
 * 2)內迴圈:拿著差值去陣列中比較判斷是否存在
 * 3)如果存在:返回兩個元素的下標
 * 4)如果不存在:繼續遍歷
 *
 * 效能分析:
 * 1)時間複雜度分析:兩層 for 迴圈,所以時間複雜度為 O(n^2)
 * 2)空間複雜度分析:不需要額外的空間,所以空間複雜度為 O(1)
 */
var twoSum = function(nums, target) {
    for(let j = 0;j < nums.length; j++){
        subtract = target - nums[j];
        for(let i = 0;i < nums.length; i++){
            if(nums[i] == subtract && i !== j){
                return [j,i]
            }else{
                continue;
            }
        }
    }
    return false;
};
//測試
const nums = [2,7,11,15];
console.log(twoSum(nums,26));
複製程式碼
▉ 法二:兩遍雜湊表

演算法思路:先遍歷陣列將下標對應的元素存到雜湊表,然後同目標值減去的值去雜湊表中檢視是否存在。

/**
 * 步驟:
 * 1)遍歷陣列資料,將根據下標和元素值存放到雜湊表中。
 * 2)目標值減去陣列元素差值並在雜湊表中查詢。
 * 3)如果存在,返回兩元素的下標。
 * 4)不存在繼續遍歷
 *
 * 效能分析:
 * 1)時間複雜度分析:隨機訪問的時間複雜度為O(1),但是需要遍歷所有資料,所以時間複雜度為 O(n)。
 * 2)空間複雜度分析:需要額外的 n 大小的空間儲存雜湊表,空間複雜度為 O(n)。
 */
var twoSum = function(nums, target) {
    var map = new Map();
    for(let i = 0;i < nums.length; i++){
        map.set(nums[i],i)
    }
    for (let j = 0; j < nums.length; j++) {
        substra = target - nums[j];
        if(map.has(substra) && map.get(substra) !== j){
            return [j,map.get(substra)]
        }
    }
}

// 測試
const nums = [2,7,11,15];
console.log(twoSum(nums,9));
複製程式碼
▉ 法三:一遍雜湊表

演算法思路:遍歷目標值減去陣列元素的差值同時判斷該值在雜湊表中是否存在差值,如果存在,則返回;否則將資料加入到雜湊表中。

/**
 * 步驟:
 * 1)遍歷目標值減去陣列元素的差值同時判斷該值在雜湊表中是否存在差值
 * 2)存在該差值,返回該元素下標
 * 3)不存在,將該差值儲存到雜湊表中繼續遍歷。
 *
 * 效能分析:
 * 1)時間複雜度分析:隨機訪問的時間複雜度為O(1),但是需要遍歷所有資料,所以時間複雜度為 O(n)。
 * 2)空間複雜度分析:需要額外的 n 大小的空間儲存雜湊表,空間複雜度為 O(n)。
 */
var twoSum = function(nums, target) {
    var map = new Map();
    for(let i = 0;i < nums.length; i++){
        substra = target - nums[i];
        if(map.has(substra)){
            return [i,map.get(substra)]
        }
        map.set(nums[i],i)
    }
    return false;
}

// 測試
const nums = [2,7,11,15];
console.log(twoSum(nums,26));
複製程式碼
▉ 總結:

1、涉及到查詢、判斷是否存在,相關的資料結構有雜湊表、平衡二叉樹、二分查詢、跳錶、二叉查詢樹。

2、使用資料結構的時候注意適用條件

3、注意對時間複雜度、空間複雜度的優化策略。

歡迎關注我個人公眾號:「一個不甘平凡的碼農」,記錄了自己一路自學程式設計的故事。
LeetCode 其他題目解析,請關注我Github:github.com/luxiangqian…

相關文章