You can do it in O(n^2). Works fine with duplicated and negative numbers.
edit as Andre noted in comment, time is with use of hash, which has 'worst case' (although it's less likely than winning in a lottery). But you can also replace hashtable with balanced tree (TreeMap in java) and get guaranteed stable O(n^2 * log(n)) solution.
Hashtable sums will store all possible sums of two different elements. For each sum S it returns pair of indexes i and j such that a[i] + a[j] == S and i != j. But initially it's empty, we'll populate it on the way.
for (int i = 0; i < n; ++i) {
// 'sums' hastable holds all possible sums a[k] + a[l]
// where k and l are both less than i
for (int j = i + 1; j < n; ++j) {
int current = a[i] + a[j];
int rest = X - current;
// Now we need to find if there're different numbers k and l
// such that a[k] + a[l] == rest and k < i and l < i
// but we have 'sums' hashtable prepared for that
if (sums[rest] != null) {
// found it
}
}
// now let's put in 'sums' hashtable all possible sums
// a[i] + a[k] where k < i
for (int k = 0; k < i; ++k) {
sums[a[i] + a[k]] = pair(i, k);
}
}
Let's say, X = a[1] + a[3] + a[7] + a[10]. This sum will be found when i = 7, j = 10 and rest = a[1] + a[3] (indexes 1 and 3 will be found from hash)