代码题(55)— 两数之和、三数之和

一、1. 两数之和数组

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。数组是无序的,返回对应下标。spa

你能够假设每一个输入只对应一种答案,且一样的元素不能被重复利用。指针

示例:code

给定 nums = [2, 7, 11, 15], target = 9
由于 nums[0] + nums[1] = 2 + 7 = 9
因此返回 [0, 1]
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { vector<int> res; if(nums.empty()) return res; unordered_map<int,int> m; for(int i=0;i<nums.size();++i) m[nums[i]]=i; for(int i=0;i<nums.size();++i) { int t = target-nums[i]; if(m.count(t) && m[t] != i) //找到,而且不是以前的数
 { res.push_back(i); res.push_back(m[t]); break; } } return res; } };

二、15. 三数之和blog

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出全部知足条件且不重复的三元组。排序

注意:答案中不能够包含重复的三元组。three

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

知足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

  首先,两数和问题这样作。先对数组中的数进行排序,再设置两个指针,一个指向头,一个指向尾。判断两数和是否等于想要的数,若是是则在结果集添加这个数组;若是小了说明左边指针指向的数小了,所以左指针右移;反之若是大了则右指针左移。 
尝试把三数和问题转化为两数和问题:一样先对数组排序,设置三个指针p,q,r,p指针指向第一个数x,则q,r要指向数组中剩余数中的两个,而且指向的两数和为-x,从而转化为两数和问题。对p指向第一个数的状况分析完毕后,不可能再有知足题意且包含x的状况,因而p右移。这样一直分析到p指向数组中倒数第三个数的状况。注意跳过全部重复的状况。get

class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> res; if(nums.size()<3) return res; sort(nums.begin(),nums.end()); // 首先排序
        vector<int> temp(3); int len = nums.size(); for(int i=0;i<len-2;++i) // 首先固定一个变量,把三数之和变为两数之和的问题。
 { temp[0] = nums[i]; int sum = -nums[i]; int j=i+1,k=len-1; while(j<k) { int curSum = nums[j]+nums[k]; if(curSum == sum) { temp[1] = nums[j++]; temp[2] = nums[k--]; res.push_back(temp); while(j<k && nums[j]==nums[j-1]) // 去重操做
                        j++; while(j<k && nums[k]==nums[k+1]) k--; } else if(curSum < sum) j++; else k--; } while(i < len-2 && nums[i+1] == nums[i]) // 对于固定的数也要去重
                i++; } return res; } };
相关文章
相关标签/搜索