(LeetCode刷題)Day01 Two Sum-兩數之和

題目描述(簡單題)

Two Sum

英文描述
在這裏插入圖片描述
我們的目標是:給定確定數組和一個目標和,在數組中找兩個數字相加等於目標和的項目,輸出這兩個數字的下標。

解法一 雙重循環

本解法傾向於暴力解法,並且比較耗費空間,因爲添加了一個多餘的vector作爲中間存儲區。

時間複雜度:因爲是兩層 for 循環,O(n2)O(n^2)

空間複雜度:O(1)O(1)

C++ 解法:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target)
     {
        vector<int> result;
        for(int i=0;i<nums.size();i++)
        {
              int tmp=target-nums[i];
              for(int j=i+1;j<nums.size();j++)
              {
                if(nums[j]==tmp)
                {
                    result.push_back(j);
                    result.push_back(i);
                    
                }
              }
        }
        return result;
    }
};

Golang解法:

func twoSum(nums []int, target int) []int {
    for i:=0;i<len(nums);i++{
        for j:=i+1;j<len(nums);j++{
            if nums[i]+nums[j]==target{
                return []int{i,j}
            }
        }
    }

    return []int{}
}

解法二 利用哈希表

在上邊的解法中,我們可以觀察下第二個 for 循環步驟。

        for j:=i+1;j<len(nums);j++{
            if nums[i]+nums[j]==target{

那麼,我們如果換一種理解方式和思路,可以得到下面的結論:

        for j:=i+1;j<len(nums);j++{
            sub = target - nums[i]
            if nums[j]==target{

第二層 for 循環無非是遍歷所有的元素,看哪個元素等於 sub ,時間複雜度爲 O(n)O(n)

那麼,有沒有一種方法,不用遍歷就可以找到元素裏有沒有等於 sub 的?

hash table !!!!

我們可以使用哈希表來解決這個問題。

我們可以把數組的每個元素保存爲 hash 的 key,下標保存爲 hash 的 value 。

這樣僅剩下需判斷 sub 在不在 hash 的 key 裏就可以了,而此時的時間複雜度僅爲 O(1)O(1)

需要注意的地方是,還需判斷找到的元素不是當前元素,因爲題目裏講一個元素只能用一次。

時間複雜度:比解法一少了一個 for 循環,降爲O(n)O(n)

空間複雜度:所謂的空間換時間,這裏就能體現出來, 開闢了一個 hash table ,空間複雜度變爲O(n)O(n)

C++解法:

class Solution
{
public:
    vector<int> twoSum(vector<int> &nums, int target)
    {
        //Key是數字,value是該數字的index
        unordered_map<int, int> hash;
        vector<int> result;
        int numsSize = int(nums.size());
        for (int i = 0; i < numsSize; i++)
        {
            int numberToFind = target - nums[i];

            //如果找到numberToFind,就return
            if (hash.find(numberToFind) != hash.end())
            {
                result.push_back(hash[numberToFind]);
                result.push_back(i);
                return result;
            }

            //如果沒有找到,把該數字的index放到hash表中
            hash[nums[i]] = i;
        }
        return result;
    }
};

視頻講解

Golang解法:

func twoSum(nums []int, target int) []int {
	num_map := make(map[int]int)
	result_list := make([]int, 2)
	for index_value, first_num := range nums {
		second_value := target - first_num
		if second_index, ok := num_map[second_value]; ok {
			result_list[0] = second_index
			result_list[1] = index_value
			return result_list
		}
		num_map[first_num]=index_value
	}
	return result_list
}

解法三 合併循環的方式

看解法二中,兩個 for 循環,他們長的一樣,我們當然可以把它合起來。複雜度上不會帶來什麼變化,變化僅僅是不需要判斷是不是當前元素了,因爲當前元素還沒有添加進 hash 裏。

C++解法:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int, int> index_map;
        vector<int> ans;
        for (int i = 0; i < nums.size(); ++i) {
            if (index_map.count(nums[i])) {
                ans.push_back(index_map[nums[i]]);
                ans.push_back(i);
                return ans;
            }
            index_map[target - nums[i]] = i;
        }
        return ans;
    }
};

Golang解法:

func twoSum(nums []int, target int) []int {
	num_map := make(map[int]int)
	result_list := make([]int, 2)
	for index_value, first_num := range nums {
		second_value := target - first_num
		if second_index, ok := num_map[second_value]; ok {
			result_list[0] = second_index
			result_list[1] = index_value
			return result_list
		}
		num_map[first_num]=index_value
	}
	return result_list
}

參考鏈接聲明

Two Sum - 知乎

關於Java的解法可以主要品讀上述的文章。

在這裏插入圖片描述
成長,就是一個不動聲色的過程,一個人熬過一些苦,才能無所不能。 ​​​​

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