Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
有三点需要注意:
1、返回的为两个元素的索引值;
2、假设有且只有一组答案;
3、同一个元素不能使用两次。
Complexity Analysis:
Time complexity: O(n2). For each element, we try to find its complement by looping through the rest of array which takes O(n) time. Therefore, the time complexity is O(n2).
Space complexity: O(1).
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> loc(2);
for (int i = 0; i < nums.size() - 1; i++) {
for (int j = i + 1; j < nums.size(); j++) {
if (nums[i] + nums[j] == target) {
loc = {
i, j};
return loc;
}
}
}
return loc;
}
};
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int length = nums.size();
vector<int> ans; //不定长数组
for (int i = 0; i < length; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] + nums[j] == target) {
ans.push_back(j);
ans.push_back(i);
return ans;
}
}
}
return ans;
}
};
对不定长数组a的操作:
a.size():获取数组的大小
a.resize():改变数组的大小
a.push_back():在数组尾部增添元素
a.pop_back():删除数组的最后一个元素
unordered_map和map类似,都是存储 (key, value) 的值,即键值对:可以通过key快速索引到value。不同的是unordered_map不会根据key的大小进行排序,存储时是根据key的hash值判断是否为要寻找的元素
Complexity Analysis:
Time complexity: O(n). We traverse the list containing n elements only once. Each look up in the table costs only O(1) time.
Space complexity: O(n). The extra space required depends on the number of items stored in the hash table, which stores at most n elements.
使用unordered_map。遍历数组,若 (target - nums[i]) 的值不在其中,将 (nums[ i ], i) 作为(key, value) 存入map中。否则,返回其对应的索引和当前数组元素的索引。
class Solution {
public:
std::vector<int> twoSum(vector<int>& nums, int target) {
std::vector<int> res; // 不定长数组
std::unordered_map<int, int> hashs; //value->index map
for (int i = 0; i < nums.size(); i++) {
if (hashs.end() != hashs.find(target - nums[i]))
// target-num[i] 在map里
{
res.push_back(hashs[target - nums[i]]);
res.push_back(i);
return res;
}
hashs.insert(std::make_pair(nums[i], i));
// 使用make_pair
// 如果不在,就插入到map中
}
return res;
}
};
也可以使用下面的方式来判断返回的两个索引的顺序:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> num_map;
vector<int> res;
for (int i = 0; i < nums.size(); i++) {
int tmp = target - nums[i];
if (num_map.find(tmp) != num_map.end()) {
int beg = i > num_map[tmp] ? num_map[tmp] : i;
int end = i > num_map[tmp] ? i : num_map[tmp];
// beg为两个索引中小的那个
// end为两个索引中大的那个
res.push_back(beg);
res.push_back(end);
break;
}
num_map[nums[i]] = i;
}
return res;
}
};
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result(2, -1);
unordered_map<int, int> m;
for (int i = 0;i < nums.size(); i++)
{
if (m.end() == m.find(target - nums[i]))
m.insert(map<int, int>::value_type(nums[i], i));
// 使用map
else
{
result[0] = m[target - nums[i]];
result[1] = i;
return result;
}
}
return result;
}
};
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
vector<int> result(2, -1);
for (int i = 0;i < nums.size(); i++)
{
if (!m.count(nums[i]))
m.insert(pair<int, int>(nums[i], i));
if (m.count(target - nums[i]))
{
int t = m[target - nums[i]];
if (t < i) // 下标不能相同
{
result[0] = t;
result[1] = i;
return result;
// nums[i]所指向的下标一定是大于target-nums[i]所对应的下标的
// 所以有r[0]和r[1]的先后顺序
}
}
}
return result;
}
};
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
// Only really have to search if there's more than 2 elements...
if(nums.size() > 2){
// So... the known solution is to use a hashmap with the stored differences...
map<int,int> summer; //
for(int i=0;i<nums.size();i++){
int theDiff = target-nums[i];
if(summer.find(theDiff)==summer.end()){
summer[nums[i]]=i;
} else {
return {
summer[theDiff],i};
}
}
}
//If there's only 2 elements, obviously that's the answer then...
return {
0,1};
}
};
第一个循环:将所有 (key, value) 存入map中;
第二个循环:查找符合题目要求的数组元素,返回其索引值。
Complexity Analysis:
Time complexity: O(n). We traverse the list containing nn elements exactly twice. Since the hash table reduces the look up time to O(1), the time complexity is O(n).
Space complexity: O(n). The extra space required depends on the number of items stored in the hash table, which stores exactly n elements.
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> num_map;
vector<int> res;
for (int i = 0; i < nums.size(); i++) {
num_map[nums[i]] = i;
}
for (int i = 0; i < nums.size(); i++) {
int tmp = target - nums[i];
if (num_map.find(tmp) != num_map.end() && num_map[tmp] != i)
// num_map[tmp] != i的目的是防止同一个元素被用两次
// e.g. nums: [3,0,8], target: 6
// 3 + 3 = 6, 但是同一个元素不能使用两次,应该排除这种情况
{
res.push_back(i);
res.push_back(num_map[tmp]);
break;
}
}
return res;
}
};
时间复杂度:O(log(n))
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> m;
vector<int> index;
for(int i = 0; i < nums.size(); i++)
{
if(m.count(target - nums[i]) != 0)
{
index.push_back(m[target - nums[i]]);
index.push_back(i);
break;
}
m[nums[i]] = i;
}
return index;
}
};
链接: 简述C++中map和unordered_map的用法.
链接: c++中map与unordered_map的区别.
需要注意的是sort完数组后原数组的顺序已经被改变,这个时候返回的索引值也出现了变化。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> a = nums;
vector<int> m, res;
sort(a.begin(), a.end()); // 改变a,原数组保持不变
for (int i = 0; i < a.size(); i++) {
int l = i + 1;
int h = a.size() - 1;
int goal = target - a[i];
while (l <= h) {
if (a[l] == goal) {
m = {
a[i], a[l]};
break;
}
else if (a[h] == goal) {
m = {
a[i], a[h]};
break;
}
else {
l++;
h--;
}
}
}
for (int i = 0; i < a.size(); i++) {
if (nums[i] == m[0] or nums[i] == m[1])
res.push_back(i);
}
return res;
}
};
1、control reached end of non_void function
一些本应带有返回值的函数到达结尾后可能并没有返回任何值,检查一下每个控制流是否都有返回值。