leetcode之两数之和c++解法


给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

方法一:暴力法

遍历每个元素x,查找是否存在一个值与target-x相等的目标元素。
时间复杂度:对每个元素都试图遍历数组的其余部分来寻找它所对应的目标元素,这将耗费O(n)的时间,n个元素所以时间复杂度是O(n2)。
空间复杂度:O(1)。

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

方法二:两遍哈希表

第一次迭代:将每个元素的值和它的索引添加到表中。
第二次迭代:检查每个元素对应的目标元素(target-nums[i])是否存在于表中。
时间复杂度:遍历两次包含n个元素的列表,哈希表的查找时间是O(1),所以时间复杂度是O(n)。
空间复杂度:所需的额外空间取决于哈希表中存储的元素数量,该表中存储了n个元素,所以空间复杂度是O(n)。

class Solution{
public:
	vector<int> twoSum(vector<int>& nums, int target){
		map<int,int> hash;
		for(int i=0;i<nums.size();i++)
			hash[nums[i]]=i;
		for(int i=0;i<nums.size();i++){
			int t=target-nums[i];
			//用find函数来定位数据出现位置,它返回的是一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器
			if(hash.find(t)!=hash.end()&&hash[t]!=i)//不能重复利用这个数组中同样的元素
				return vector<int>{i,hash.find(t)->second};//first访问map的第一个元素key,second访问第二个元素value
  		}
		return vector<int>();
	}
};

方法三:一遍哈希表

在第一遍遍历元素插入到表中之前,先检查表中是否已经存在当前元素对应的目标元素,如果已经存在,即找到了对应解,将其返回,如果不存在,将当前元素插入到表中继续对下一个元素进行操作。
时间复杂度:遍历包含n个元素的列表一次,哈希表每次查找花费O(1)的时间,因此时间复杂度是O(n)。
空间复杂度:所需的额外空间取决于哈希表中存储的元素数量,该表最多需要存储n个元素,所以空间复杂度是O(n)。

class Solution{
public:
	vector<int> twoSum(vector<int>& nums, int target){
			map<int,int> hash;
			for(int i=0;i<nums.size();i++){
					int t= target-nums[i];
					if(hash.find(t)!=hash.end())
						return vector<int>{hash.find(t)->second,i}; //当前元素与之前插入表中的元素进行比对,所以哈希表中元素的索引在前,当前元素序号在后
					hash[nums[i]]=i;
		}
		return vector<int> {};
	}
};

猜你喜欢

转载自blog.csdn.net/mbskypan/article/details/89113231