(LeetCode刷题)Day01 Two Sum-两数之和

题目描述(简单题)

Two Sum

英文描述
在这里插入图片描述
我们的目标是:给定确定数组和一个目标和,在数组中找两个数字相加等于目标和的项目,输出这两个数字的下标。

解法一 双重循环

本解法倾向于暴力解法,并且比较耗费空间,因为添加了一个多余的vector作为中间存储区。

时间复杂度:因为是两层 for 循环, O ( n 2 ) O(n^2) O(n2)

空间复杂度: O ( 1 ) 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) O(n)

那么,有没有一种方法,不用遍历就可以找到元素里有没有等于 sub 的?

hash table !!!!

我们可以使用哈希表来解决这个问题。

我们可以把数组的每个元素保存为 hash 的 key,下标保存为 hash 的 value 。

这样仅剩下需判断 sub 在不在 hash 的 key 里就可以了,而此时的时间复杂度仅为 O ( 1 ) O(1) O(1)

需要注意的地方是,还需判断找到的元素不是当前元素,因为题目里讲一个元素只能用一次。

时间复杂度:比解法一少了一个 for 循环,降为 O ( n ) O(n) O(n)

空间复杂度:所谓的空间换时间,这里就能体现出来, 开辟了一个 hash table ,空间复杂度变为 O ( n ) 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的解法可以主要品读上述的文章。

在这里插入图片描述
成长,就是一个不动声色的过程,一个人熬过一些苦,才能无所不能。 ​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值