I just used hashmap to reduce O(n^3) to O(n^2), and used a "histogram" like set to avoid duplicate. You may further optimize this code using similar idea if you do not want sort.

```
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> r = new ArrayList<>();
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
Set<Double> set = new HashSet<Double>();
int l=nums.length;
int min=0;
for(int i=0;i<l;i++){
min=min<nums[i]?min:nums[i];
map.put(-nums[i],i);
}
for(int i=0;i<l-1;i++){
for(int j=i+1;j<l;j++){
Integer key=map.get(nums[i]+nums[j]);
if(key!=null && key!=i && key!=j){
double value=(1<<(nums[i]-min))+(1<<(nums[j]-min))+(1<<(nums[key]-min));
if(set.add(value) ){
List<Integer> tmp = new ArrayList<>();
tmp.add(nums[i]);
tmp.add(nums[j]);
tmp.add(nums[key]);
r.add(tmp);
}
}
}
}
return r;
}
```