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)。
結束語
上面就是關於《兩數之和》的題解,下週同一時間我們將繼續爲大家帶來更多的題目。
歡迎大家關注我的公衆號“風紙”,或是掃下面的二維碼關注👇