【LeetCode每週一題】 兩數之和

LeetCode是一個著名的在線編程評測平臺,它收錄了很多公司的面試算法題。計劃將在每週一(本次爲搬運之前發佈的內容)爲大家選擇一道LeetCode的題目,並提供對應的解題思路及示例代碼(C#實現)。文章將同步發表於風紙、HelloCopyer微信公衆號上。

作爲題解系列的開篇,這裏爲大家帶來了難度較低的第一題——兩數之和。兩數之和這個題目主要考察的是哈希表的使用。當然,也可以使用如下文解法一一樣使用暴力求解。

描述

給定一個整數數組nums和一個目標值target,請你在該數組中找出和爲目標值的那兩個整數,並返回他們的數組下標。

你可以假設每種輸入只會對應一個答案。但是,數組中同一個元素不能使用兩遍。

示例

輸入

[2, 7, 11, 15]
9

輸出

[0, 1]

解法一

第一種解法是對該題的暴力求解方法,邏輯爲遍歷數組中的每一個元素,並尋找是否存在數組中另外一個元素與其之和爲目標值。該解法時間複雜度爲O(N^2),空間複雜度爲O(1)。

public int[] TwoSum(int[] nums, int target)
{
    for (var i = 0; i < nums.Length; i++)
    {
        for (var j = 0; j < i; j++)
        {
            if (nums[i] + nums[j] == target)
            {
                return new int[2] { i, j };
            }
        }
    }

    return new int[2];
}

解法二

第二種解法是採用通過空間換取時間的方式,採用額外的存儲結構支持降低其時間複雜度。下列示例中,採用了Dictionary類存放遍歷過的元素的值及其下標,除Dictionary外也可選用HashTable等結構。構造Dictionary實例時,採用了數組的長度作爲字典的容量,避免極端情況下大量觸發Resize對時間造成影響。該解法的主要邏輯爲:對數組的元素進行遍歷,在輔助的存儲結構中尋找與當前元素的和等於目標值的元素,當字典中存在則返回該元素及當前元素的下標,否則將當前元素存放至輔助存儲結構中。對於Dictionary實例,不可添加相同鍵的元素,所以在實現中若字典中已存在相同的值將不再添加。

public int[] TwoSum(int[] nums, int target) {
    // Dictionary<int, int> dict = new Dictionary<int, int>();
    Dictionary<int, int> dict = new Dictionary<int, int>(nums.Length);

    for (var i = 0; i < nums.Length; i++)
    {
        int remainder = target - nums[i];

        if (dict.ContainsKey(remainder))
        {
            return new int[2] { dict[remainder], i };
        }
        else if (!dict.ContainsKey(nums[i]))
        {
            // 若dict中已存在相同的值則跳過
            dict.Add(nums[i], i);
        }
    }

    return new int[2];
}

對於解法二,其時間複雜度爲O(N)(Dictionary中查找元素時間複雜度爲O(1)) ,空間複雜度爲O(N)。

結束語

上面就是關於《兩數之和》的題解,下週同一時間我們將繼續爲大家帶來更多的題目。

歡迎大家關注我的公衆號“風紙”,或是掃下面的二維碼關注👇
風紙

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章