LeetCode No1题解。两数之和

LeetCode No1题解。两数之和

ps:题目,给定一个整数数组和一个目标值,请你在数组中找出和为目标值的两个数的下标。假设返回的答案仅有一对且同一个整数不可以重复使用。

这是LeetCode开篇第一题,大部分人应该都刷过这道题。我是为了找工作才刷的LeetCode,也就一个月。开始做的时候,看了看题解也就过去了,后来在华为北研所的面试时手撕代码就是这道题。果然欠的账总是要还的。面试官和我说他特别喜欢这道题,既可以暴力简单解决,又可以完美优化。小伙伴们注意你要是面试华为北研所很可能遇到这个问题哟

下面详讲三种思路

第一种,暴力简单解决

思路:很简单,就是用两个for循环去挨个试,过于简单不赘述了。时间复杂度O(n^2)

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        for(int i=0;i<nums.size();++i){
            for(int j=0;j<nums.size();++j){
                if(i!=j && nums[i] + nums[j] == target){
                    return {i,j};
                }
            }
        }
        return {};//Leetcode 中末尾必须有返回return,否则报错
    }
}

补充说明一下,因为是返回数组下标,所以需要考虑按顺序返回。此时i定是小于j的,因为他是按数组顺序查找,定住i值,j从头遍历。

第二种,使用key-value 映射,两次遍历

思路:使用c++提供的STL库中的unordered_map。因为此处不需要排序,所以使用unordered会使建立映射时的性能提高。时间复杂度O(n)。
总共进行两次遍历:

  1. 第一次遍历,用于建立映射,key是数组内整数,value是该整数的下标。
  2. 第二次遍历,根据建立好的映射关系,去寻找符合的两个整数。
class Solution {
public:   
 vector<int> twoSum(vector<int>& nums, int target) {
   unordered_map<int,int> rec;
   for(int i=0;i<nums.size();i++){            
   	rec[nums[i]] = i;       
   }                             
   for(int i=0;i<nums.size();i++){            
   	if(rec.find(target-nums[i]) != rec.end() && rec[target-nums[i]] != i)                   
   		 return {i , rec[target-nums[i]]};       
   	 }       
    return {};    	
 }
};

第三种,使用key-value 映射,一次遍历

思路:仔细观察第二种解法,他是使用两次遍历,第一次是建立映射关系,第二次是寻找目标值对,那么优化的思路就很清晰,就是采用一次遍历即建立映射关系同时又寻找目标值对。时间复杂度同上O(n)。

class Solution {
public:    
	vector<int> twoSum(vector<int>& nums, int target) {        		    
		unordered_map<int,int> res;
        	int num = (int)nums.size();        
       		for(int i = 0;i<num;++i){            	
       		 	unordered_map<int,int>::iterator pos = res.find(target - nums[i]);
       		 	if(pos != res.end() && pos->second != i){
                		return  {pos->second,i};           
                	}           
                        else{                
                        	res[nums[i]] = i;            
                        }// if...else       
                 }//for       
                 return{};    
        }
};

限于自己水平,也不知道是否给大家讲清楚和漏掉重要的东西,若是有错误或者疑惑的地方随时欢迎私信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值