O(NlogN): Copy the numbers and sort first, and then use two pointers to get the two numbers we want, then check the indices of these two numbers. One from head and the other from tail to avoid duplication if two numbers are the same.

```
vector<int> twoSumNlogN(vector<int> &numbers, int target) {
vector<int> tmp = numbers;
sort(tmp.begin(), tmp.end());
int l = 0, r = (int) tmp.size() - 1;
while (l < r) {
int mid = tmp[l] + tmp[r];
if (mid == target) break;
if (mid < target) ++l; else --r;
}
int index1 = 0, index2 = 0;
for (int i = 0; i < tmp.size(); ++i) {
if (numbers[i] == tmp[l]) { index1 = i; break; }
}
for (int i = (int)tmp.size() - 1; i >= 0; --i) {
if (numbers[i] == tmp[r]) { index2 = i; break; }
}
if (index1 > index2) { index1 ^= index2; index2 ^= index1; index1 ^= index2; }
vector<int> result {index1 + 1, index2 + 1};
return result;
}
```

O(N): Use map to record the index of each element, and check if the wanted complementary element exists in the map. Special process the two numbers equal situation.

```
vector<int> twoSum(vector<int> &numbers, int target) {
int index1 = 0, index2 = 0;
// Special Case: target = a + a, cannot be solved by map
for (int i = 0; i < numbers.size(); ++i) {
if (numbers[i] == target / 2) {
if (index1 == 0) index1 = i + 1; else index2 = i + 1;
}
}
if (index1 > 0 && index2 > 0) {
vector<int> result { index1, index2 };
return result;
}
unordered_map<int, int> m;
for (int i = 0; i < numbers.size(); ++i) m[numbers[i]] = i + 1;
for (int i = 0; i < numbers.size(); ++i) {
if (m[target - numbers[i]] && m[target - numbers[i]] != i + 1) {
index1 = m[numbers[i]];
index2 = m[target - numbers[i]];
break;
}
}
if (index1 > index2) { index1 ^= index2; index2 ^= index1; index1 ^= index2; }
vector<int> result { index1, index2 };
return result;
}
```