一、两数之和的扩展
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Set<List<Integer>> set = new HashSet<>();
for(int i=0; i<nums.length; i++){
Map<Integer,Integer> map = new HashMap<>();
for(int j=i+1; j<nums.length; j++){
int complement = -nums[i]-nums[j];
if(map.containsKey(complement)){
Integer[] tmp = new Integer[]{nums[i],nums[j],complement};
Arrays.sort(tmp);
set.add(Arrays.asList(tmp));
}
map.put(nums[j],j);
}
}
return new ArrayList<>(set);
}
}
注意:
- 关于数组的操作在
Arrays
(注意有s)中,例如:排序Arrays.sort(tmp)
->tmp直接变,无需返回值 - 数组与集合相互转换:
Arrays.asList()
(数组->list) list.toArray()
(list->数组) - 集合与集合相互转换:
new ArrayList<>(set)
(set->list) new HashSet<>(list)
(list->set)
错误原因:超出时间限制

双指针解法:先用一个 for 循环遍历数组,对于每个数字,使用双指针在数组的剩余部分查找和为 0 的另外两个元素。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new LinkedList<>();
Arrays.sort(nums);
for(int i=0; i<nums.length-2; i++){
int left=i+1, right=nums.length-1, complement=-nums[i];
if(i==0 || i>0 && nums[i]!=nums[i-1]){
while(left<right){
if(complement == nums[right]+nums[left]){
Integer[] tmp=new Integer[]{nums[i],nums[right],nums[left]};
res.add(Arrays.asList(tmp));
while(left<right && nums[left]==nums[left+1]){left++;}
while(left<right && nums[right]==nums[right-1]){right--;}
left++;
right--;
}
else if(complement > nums[right]+nums[left]){
left++;
}
else{
right--;
}
}
}
}
return res;
}
}
注意:
LinkedList
中有ed
;不存在HashlList
- 在
if(complement == nums[right]+nums[left])
判断后,还要判断if(complement > nums[right]+nums[left])
,确保后面有 - 在
for
内还有while
循环,用于循环后面两个数 Arrays.asList(1,2,3);
or Integer[] tmp = new Integer[]{1,2,3}; Arrays.asList(tmp);