LeetCode数字之和总结

此总结包含题目(两数之和,三数之和,最接近的三数之和,四数之和,两数之和 II - 输入有序数组

1.两数之和

/*
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
*/
 public int[] twoSum(int[] nums, int target) {
      //  map中的 key 某个之前的数   value 这个数出现的位置
     HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
     for(int i = 0;i < nums.length;i++){
         int k =  target - nums[i];
         if(map.containsKey(k)){
             return new int[]{map.get(k),i};
         }
         map.put(nums[i],i);
     }
     return new int[] { -1, -1 };    
 }

2. 三数之和

/*
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
*/
public List<List<Integer>> threeSum(int[] nums) {
    List<List<integer>> list = new ArrayList<List<Integer>>();
    Arrays.sort(nums);
    for(int i = 0;i < nums.length - 2;i++){
        if(nums[i]>0) break;
        if(i==0||nums[i] != nums[i-1]){
            List<List<integer>> tmp = mytwoSum(nums,i+1,-nums[i]);
            for(List<integer> cur:tmp){
                cur.add(0,nums[i]);
                list.add(cur);
            }
        }
    }
    rerurn list;
}

public List<List<Integer>> mytwoSum(int[] nums, int begin, int target) {
    int L = begin;
    int R = nums.length-1;
    List<List<Integer>> ans = new ArrayList<List<Integer>>();
    while(L<R){
        if(nums[L] + nums[R] < target){
            L++;
        }else if(nums[L] + nums[R] > target){
            R--;
        }else{ // 进入else表示找到了
            // 1. begin是第一个开始 2. 当前和前一个不等
            if(L==begin||nums[L-1] != nums[L]){
                List<Integer> M = new ArrayList<Integer>();
                M.add(nums[L]);
                M.add(nums[R]);
                ans.add(M);
            }
            L++;
        }
    }
    return ans;
}

3. 最接近的三数之和

/*
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
*/
public int threeSumClosest(int[] nums, int target) {
    int sum1 = nums[0] + nums[1] + nums[2]; //首先随便计算三数之和
    int diff = Math.abs(target - sum1); // 差值
    Arrays.sort(nums);
    for(int i = 0;i < nums.length - 2;i++){
        if(i > 0 && nums[i-1] == nums[i]) continue;
        int m = i + 1;
        int n = nums.length -1;
        while(m<n){
            int tmp = nums[i] + nums[m] + nums[n];
            int t_diff = Math.abs(target - tmp);
            if(t_diff < diff){
                diff = t_diff;
                sum1 = tmp;
            }
            if(tmp < target){
                m++;
            }else{
                n--;
            }
        }
    }
    return sum1;
}

4. 四数之和

/*
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] :
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
*/

public List<List<Integer>> fourSum(int[] nums, int target) {
	List<List<Integer>> list = new ArrayList<List<Integer>>();
    Arrays.sort(nums);
    for(int i = 0;i < nums.length - 3;i++){
        if(i==0||nums[i] != nums[i-1]){
            List<List<Integer>> tmp = myThreeSum(nums,i+1,target-nums[i]);
            for(List<Integer> cur:tmp){
                cur.add(0,nums[i]);
                list.add(cur);
            }
        }
    }
    return list;	
}

public List<List<Integer>> myThreeSum(int[] nums, int begin, int target) {
	List<List<Integer>> list = new ArrayList<List<Integer>>();
    for(int i = begin;i < nums.length - 2;i++){
        if(i == begin||nums[i] != nums[i-1]){
            List<List<Integer>> tmp = mytwoSum(nums,i+1,target-nums[i]);
            for(List<Integer> cur:tmp){
                cur.add(0,nums[i]);
                list.add(cur);
            }
        }
    }
    return list;
}

public List<List<Integer>> mytwoSum(int[] nums, int begin, int target) {
    int L = begin;
    int R = nums.length-1;
    List<List<Integer>> ans = new ArrayList<List<Integer>>();
    while(L<R){
        if(nums[L] + nums[R] < target){
            L++;
        }else if(nums[L] + nums[R] > target){
            R--;
        }else{ // 进入else表示找到了
            // 1. begin是第一个开始 2. 当前和前一个不等
            if(L==begin||nums[L-1] != nums[L]){
                List<Integer> M = new ArrayList<Integer>();
                M.add(nums[L]);
                M.add(nums[R]);
                ans.add(M);
            }
            L++;
        }
    }
    return ans;
}


// 解法二
public List<List<Integer>> fourSum2(int[] nums, int target) {
        List<List<Integer>> list = new ArrayList<List<Integer>>();
		if(nums.length<4) return list;
		Arrays.sort(nums);
		for(int i=0;i<nums.length-3;i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
			for(int j=i+1;j<nums.length-2;j++) {
                if (j > i+1 && nums[j] == nums[j - 1]) continue;
				int m = j+1;
				int n = nums.length-1;
				while(m<n) {
					int sum = nums[i]+nums[j]+nums[m]+nums[n];
					if(sum==target) {
						List<Integer> tmpIntegers = new ArrayList<Integer>();
						tmpIntegers.add(nums[i]);
						tmpIntegers.add(nums[j]);
						tmpIntegers.add(nums[m]);
						tmpIntegers.add(nums[n]);
						list.add(tmpIntegers);
                        while (m < n && nums[m] == nums[m + 1]) ++m;
	                    while (m < n && nums[n] == nums[n - 1]) --n;
                        m++;
						n--;
					}else if (sum<target) {
						m++;
					}else {
						n--;
					}
				}
			}
		}
		
		return list;
    }

5. 两数之和 II - 输入有序数组

/*
给定一个已按照 非递减顺序排列  的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。

函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
*/
public int[] twoSum(int[] numbers, int target) {
        int point_i = 0;
        int point_j = numbers.length-1;
        while(point_i<point_j){
            if(numbers[point_i]+numbers[point_j] == target) return new int[]{point_i+1,point_j+1};
            else if(numbers[point_i]+numbers[point_j] < target) point_i++;
            else{
                point_j--;
            }
        }
        return new int[]{point_i,point_j};
 }

6. 总结

此类题目主要用到哈希表来存储元素,以达到快速判断的目的,此外还有利用已经排好序的数组后的特性,利用双指针来加速检索符合要求的元素

原文地址:https://www.cnblogs.com/wailaifeike/p/15429406.html