제목 설명
해결책
처음 :
반복을 판단하기 위해 트리플로 구성된 정수 범위를 -999에서 999까지 사용하고 태그 배열 레지스터를 사용하십시오.
그런 다음 각 숫자에 대해 두 숫자의 합이 0이라는 것을 알아 내면됩니다.
그리고 나서 두 수의 합의 문제로 바뀝니다.
두 숫자의 합에 대해 이중 포인터 솔루션 또는 해시 테이블을 한 번 확인하는 방법이 있음을 알고 있지만 해시 테이블은 정렬되지 않은 배열에 구축 될 수 있습니다. 이중 포인터는 정렬 된 배열에서만 빌드 할 수 있습니다.
처음 어리 석었을 때 실제로 해시 테이블을 사용했습니다.
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
public class Solution {
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
//对数组排序先
Arrays.sort(num);//升序
//然后利用数组标记是否重复
boolean[] register = new boolean[2000];
if(num==null ||num.length<3) return result;
Map<Integer,Integer> map = new HashMap<>();
int pre = 0;//上一个插入数据的最左边的坐标
for(int i=0;i<num.length;i++){
int target = 0-num[i];
for(int j=i+1;j<num.length;j++){
if(map.containsKey(target-num[j])){
//找到了一组
int k = (int)map.get(target-num[j]);//j必然大于k
int index;
if(num[i]<0){
index = (int)(Math.abs(num[i])*100+ Math.abs(num[j])*10+Math.abs(num[k]));
if(register[index]==false){
//没有加入过
ArrayList<Integer> one = new ArrayList<>();
one.add(num[i]);
one.add(num[k]);
one.add(num[j]);
result.add(one);
register[index]=true;//标记
}
}else{
index = (int)(Math.abs(num[i])*100+ Math.abs(num[j])*10+Math.abs(num[k])+1000);//正数需要映射
if(register[index]==false){
//没有加入过
ArrayList<Integer> one = new ArrayList<>();
one.add(num[i]);
one.add(num[k]);
one.add(num[j]);
result.add(one);
register[index]=true;
}
}
}else{
map.put(num[j],j);
}
}
map.clear();//重新记录
}
//它要按照遍历的坐标顺序添加进去。。。所以还要改
return result;
}
}
추가되는 순서가 판단에 부합해야하며 먼저 오는 사람이 먼저 추가 할 것입니다. 따라서 이중 포인터를 사용하십시오.
두 번째 :
labuladong에서 언급 된 이진 검색을 엄격히 따르십시오.주의, 다음 코드를 빠르게 작성할 수 있습니다.
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
public class Solution {
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
//对数组排序先
Arrays.sort(num);//升序
//然后利用数组标记是否重复
boolean[] register = new boolean[2000];
if(num==null ||num.length<3) return result;
for(int i=0;i<num.length;i++){
int target = 0-num[i];
//利用双指针:
int left = i+1,right = num.length-1;
while(left<right){
//[left,right)
if(num[left]+num[right]>target){
//变小
right--;
}else if(num[left]+num[right]<target){
left++;
}else if(num[left]+num[right]==target){
//判断重复性:
int index;
if(num[i]<0){
index = (int)(Math.abs(num[i])*100+ Math.abs(num[left])*10+Math.abs(num[right]));
if(register[index]==false){
//没有加入过
ArrayList<Integer> one = new ArrayList<>();
one.add(num[i]);
one.add(num[left]);
one.add(num[right]);
result.add(one);
register[index]=true;//标记
}
}else{
index = (int)(Math.abs(num[i])*100+ Math.abs(num[left])*10+Math.abs(num[right])+1000);//正数需要映射
if(register[index]==false){
//没有加入过
ArrayList<Integer> one = new ArrayList<>();
one.add(num[i]);
one.add(num[left]);
one.add(num[right]);
result.add(one);
register[index]=true;
}
}
//找到一组:
left++;
}
}
}
return result;
}
}