## 一、题目描述
![](https://box.kancloud.cn/2016-01-05_568bb5e7e0b0b.jpg)
基本意思是给定一组整数和一个常数target,试图在这一组数里找到两个数使得两者的和等于target,结果要求返回两个数的下标。
## 二、解题思路
思路一:使用暴力算法实现,这种情况下空间复杂度为O(1),但是时间复杂度为O(n^2),会超时。
思路二:使用hash表,存储每个数对应的下标,事件复杂度为O(n)。这样在查找某个值存不存在只需要常数时间。
~~~
//LeetCode, Two Sum
// 时间复杂度O(n),空间复杂度O(n)
class Solution {
public:
vector<int> twoSum(vector<int> &num, int target) {
unordered_map<int, int> mapping;
vector<int> result;
for (int i = 0; i < num.size(); i++) {
mapping[num[i]] = i;
}
for (int i = 0; i < num.size(); i++) {
const int gap = target - num[i];
if (mapping.find(gap) != mapping.end() && mapping[gap] > i) {
result.push_back(i + 1);
result.push_back(mapping[gap] + 1);
break;
}
}
return result;
}
};
~~~
思路三:先排序(前提),然后利用头指针i和尾指针j找到两个数使得他们的和等于target。这种情况下,存在以下三种判断结果:
~~~
1.i+j = target,此时i和j就是能够满足条件的两个数,判断结束。
2.i+j > target, j不是满足条件的两个数,执行--j,继续判断;
3.i+j < target, i不是满足条件的两个数,执行++i,继续判断;
~~~
由于数组中可能存在相同的元素,并且满足条件的两个元素是相同的,因此,在找到第一个元素的坐标之后,需要更改第一个元素的值,为了方便起见,可以将第一个元素的值更改为第二个元素减去1,然后再寻找第二个元素的坐标。
该方法的核心代码:
~~~
//Two sum
int i = starting; //头指针
int j = num.size() - 1; //尾指针
while(i < j) {
int sum = num[i] + num[j];
if(sum == target) {
store num[i] and num[j] somewhere;
if(we need only one such pair of numbers)
break;
otherwise
do ++i, --j;
}
else if(sum < target)
++i;
else
--j;
}
~~~
这种方法存在以下边界条件,即当i>=j时,不存在两个元素的和等于给定的值,这种方法的时间复杂度O(n),空间复杂度为O(1)。
上面的方法的前提是要对数组进行排序(排序的时间复杂度为O(nlogn)),然后使用上面的算法来寻找满足条件的两个元素,总的时间复杂度为O(nlogn)+O(n)=O(nlogn),比起暴力算法的O(n^2)的时间复杂度大大改善。
## 三、解析
这道题属于面试里面一类经典的问题, 主要考察是否能够合理利用排序并设计出高效的算法。在设计算法时,需要考虑到数组事先并没有经过排序。另一个需要注意的地方是该题需要返回的是下标,而不是数字本身。
自己的代码需要进一步完善,后续更新。。。
参考链接:
[http://blog.csdn.net/sheng_ai/article/details/44211687](http://blog.csdn.net/sheng_ai/article/details/44211687)
[https://github.com/soulmachine/leetcode](https://github.com/soulmachine/leetcode)
- 前言
- 2Sum
- 3Sum
- 4Sum
- 3Sum Closest
- Remove Duplicates from Sorted Array
- Remove Duplicates from Sorted Array II
- Search in Rotated Sorted Array
- Remove Element
- Merge Sorted Array
- Add Binary
- Valid Palindrome
- Permutation Sequence
- Single Number
- Single Number II
- Gray Code(2016腾讯软件开发笔试题)
- Valid Sudoku
- Rotate Image
- Power of two
- Plus One
- Gas Station
- Set Matrix Zeroes
- Count and Say
- Climbing Stairs(斐波那契数列问题)
- Remove Nth Node From End of List
- Linked List Cycle
- Linked List Cycle 2
- Integer to Roman
- Roman to Integer
- Valid Parentheses
- Reorder List
- Path Sum
- Simplify Path
- Trapping Rain Water
- Path Sum II
- Factorial Trailing Zeroes
- Sudoku Solver
- Isomorphic Strings
- String to Integer (atoi)
- Largest Rectangle in Histogram
- Binary Tree Preorder Traversal
- Evaluate Reverse Polish Notation(逆波兰式的计算)
- Maximum Depth of Binary Tree
- Minimum Depth of Binary Tree
- Longest Common Prefix
- Recover Binary Search Tree
- Binary Tree Level Order Traversal
- Binary Tree Level Order Traversal II
- Binary Tree Zigzag Level Order Traversal
- Sum Root to Leaf Numbers
- Anagrams
- Unique Paths
- Unique Paths II
- Triangle
- Maximum Subarray(最大子串和问题)
- House Robber
- House Robber II
- Happy Number
- Interlaving String
- Minimum Path Sum
- Edit Distance
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock II
- Best Time to Buy and Sell Stock III
- Best Time to Buy and Sell Stock IV
- Decode Ways
- N-Queens
- N-Queens II
- Restore IP Addresses
- Combination Sum
- Combination Sum II
- Combination Sum III
- Construct Binary Tree from Inorder and Postorder Traversal
- Construct Binary Tree from Preorder and Inorder Traversal
- Longest Consecutive Sequence
- Word Search
- Word Search II
- Word Ladder
- Spiral Matrix
- Jump Game
- Jump Game II
- Longest Substring Without Repeating Characters
- First Missing Positive
- Sort Colors
- Search for a Range
- First Bad Version
- Search Insert Position
- Wildcard Matching