leecode中有两数之和 三数之和 四数之和等
两数之和可利用hashmap快速求解
三数之和 若转化为两数组之和做 反正我是没解出来
前天晚上 还提醒自己 如果需要多个循环 可借用双指针或者从后开始处理
今天就没想到~!!!!!!!
错误解法1——暴力解法
HashMap hash=new HashMap();
List<List<Integer>> list=new LinkedList<>();
List<Integer> list2;
for(int i=0;i<nums.length;i++){
tar=-1*nums[i];
for(int j=0;j<nums.length;i++){
if(j==i){
continue;
}else{
if(hash.containsKey(nums[j])){
list2=new LinkedList<>();
list2.add(nums[i]);
list2.add(nums[j]);
list2.add(tar-nums[j]);
//hash.put(nums[j],tar-nums[j]);//这里面一组就是其中一对 再求反便可
list.add(list2);
}
hash.put(tar-nums[j],nums[j]);
}
}
}
错误解法2——每个数组只考虑一次情况,即在双指针的情况下,只遍历一次
while(left<right){//这样 每组只有一组符合的数据 因为只循环一次。
if((nums[left]+nums[right])<tem){
++left;
}else if((nums[left]+nums[right])>tem){
--right;
}else{
list2=new LinkedList<>();
list2.add(-1*tem);
list2.add(nums[left]);
list2.add(nums[right]);
list.add(list2);
left=((left+1)==nums.length-1)?++left:--right;
}
}
正解
public List<List<Integer>> threeSum(int[] nums) {
//之前有遇到过四数之和 无解
//类似的哈希表算法:242 1002 349 202 1 454 383 15 18
//三数之和转化为 两数之和问题?
//三数之和 中加入双指针解决
//升序
Arrays.sort(nums);
LinkedList<List<Integer>> list=new LinkedList();
if(nums==null||nums.length<2) return list;
if(nums[0]>0) return list;
List<Integer> list2;
int tem=0;
int left=0;
int right=0;
int sum=0;
for(int i=0;i<nums.length;i++){
tem=nums[i];
if(i>=1){
if(nums[i]==nums[i-1]) continue;
}
left=i+1;
right=nums.length-1;
while (left<right){
sum=tem+nums[left]+nums[right];
if (sum==0){
list2=new LinkedList<>();
list2.add(tem);
list2.add(nums[left]);
list2.add(nums[right]);
list.add(list2);
while (left<right&&nums[left]==nums[left+1]) ++left;//这里是去重 也是最难的一部分
while (left<right&&nums[right]==nums[right-1]) --right;
++left;//这里才是关键 上面确实去重 往后走了一步 但是 数值并没变 所以要继续走一步 即总共走两步
--right;
}else if(sum<0) ++left;
else if(sum>0) --right;
}
}
return list;
}
核心在于这两步
在while中,sum是三数之和,
若sum不等于0,那么进行左右移动
如果sum==0 存完之后,判断一下left的右边一位,和right的左边一位是否相等;
01如果相等,那么跳到该步,而下面两个while循环,会进一步靠中间一步,一来彻底不走重复 (A,A,B——sum==0时,在A,判断之后右一位相等,则while继续走到B)
当然也会想到如果是(A,X,A)的情况 left是A,right也是A,那么两个小while之后 left和right都是X了,注意!:A+A+tem=0,如果X==A那么中间那步不要也行,因为前任保存了,如果X!=A,那么X+X+tem肯定不为0,所以最后也不走!
直呼巧妙