外传
经过室友推荐blog转战Markdown编辑,初次使用还觉得挺不方便需要那么多快捷键,不如鼠标点的快。今天这一篇文章才写一半就觉得很好用,就像电脑操作用鼠标点击和windows快捷键操作一样爽,在此向还没转战的朋友推荐,顺便练习自己的操作。
不方便的是代码高亮显示不好。参考快速上手
记录插入链接格式
题目
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].
题意
给定一个整型数组和一个整数target,当数组中两个元素的和等于target,返回这两个元素的索引。
注意
- 返回的索引是从0开始还是从1开始
- 无解返回什么
- 多个解返回什么
- 该题保证了有唯一解并且同一个元素不可能使用两次
思路1
时间复杂度:O(n),查找表实现
将nums中的元素统计出现的频率,遍历nums查找target-nums[i]的元素是否存在,存在则返回i和target-nums[i]元素索引。之前的题目使用map统计频次都是遍历一遍nums[i],这里的意思是nums[i]为键索引i为值(建立了映射关系),如果该题也这样做会产生一个问题就是当nums[i]中出现重复元素时。e.g:nums={3,3},target = 6。那么在统计元素出现的频次时会将键为3的值索引覆盖一次而失败。
这里解决的办法是,在统计nums[i]频次的时候,就开始查找历史上出现过target-nums[i],即使有重复元素被覆盖,也不会影响我们后续的查找。
代码
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> mymap;
for(int j=0;j<nums.size();j++)
{
int temp = target - nums[j];
if(mymap.find(temp)!=mymap.end())//在统计频率的时候,查找元素是否存在
{
int res[2]={j,mymap[temp]};
return vector<int> (res,res+2);
}
mymap[nums[j]] = j;
}
throw invalid_argument("ERROE");
}
};
结果
思路2
时间复杂度O(nlogn)+O(n),排序后,对撞指针
这道题第一次读是如此的熟悉,马上使用对撞指针来做(之前是有序数组),结果发现是无序的,那就排序嘛,排序打乱了原先的索引信息,怎么返回?还怎么玩?
那就维护index的信息,由于index是唯一的那么就创建一个map,index为键nums[index]为值。再对map按照值排序。
唯一需要注意的是map按照值来排序,需要转为vector,调用sort,写成lamda表达式,就不需要像451变成类的静态成员变量
由于需要map转vector索性一开始就使用vector pair 来存储。
代码
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<pair<int, int>> record;
for (int i = 0; i < nums.size();i++)
{
record.push_back({ i, nums[i] });
}
sort(record.begin(), record.end(), [](const pair<int, int> &l, const pair<int, int> &r){ return l.second < r.second; });
int l = 0, r = record.size() - 1;
int re[2] = {0};
while (l < r)
{
if (target == (record[l].second + record[r].second))
{
re[0] = record[l].first;
re[1] = record[r].first;
break;/*return vector<int>(re, re + 2);*/
}
else if (target >(record[l].second + record[r].second))
{
l++;
}
else
{
r--;
}
}
return vector<int>(re, re + 2);
}
};