zoukankan      html  css  js  c++  java
  • lettcode 15: 三数之和

    /**
     * @Class ThreeSum
     * @Description
     * 给你一个包含 n 个整数的数组 nums,
     * 判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?
     * 请你找出所有满足条件且不重复的三元组。
     *
     * 注意:答案中不可以包含重复的三元组。
     *
     * 给定数组 nums = [-1, 0, 1, 2, -1, -4],
     *
     * 满足要求的三元组集合为:
     * [
     *   [-1, 0, 1],
     *   [-1, -1, 2]
     * ]
     *
     * @Author 10256137
     * @Date 2020/6/12
     **/
    public class ThreeSum {
    }
    
    /**
     * 解法2:穷举法,利用排序去重,再逐个穷举
     * 时间复杂度:O(n^3)
     * 空间复杂度:O(n)
     */
    public List<List<Integer>> threeSum(int[] nums) {
    
    	Arrays.sort(nums);
    
    	if(nums== null || nums.length==0){
    		return new ArrayList<>();
    	}
    
    	List<List<Integer>> res = new ArrayList<>();
    	for (int i = 0; i < nums.length; i++) {
    		if(i>0 && nums[i]== nums[i-1]) continue;  // 去重
    		for (int j = i+1; j <nums.length ; j++) {
    			if(j>i+1 && nums[j]== nums[j-1]) continue;
    			for (int k = j+1; k < nums.length; k++) {
    				if(k>j+1 && nums[k] == nums[k-1]) continue;
    				if(nums[i] + nums[j] + nums[k] == 0){
    					 List<Integer> integers = new ArrayList<>();
    					 integers.add(nums[i]);
    					 integers.add(nums[j]);
    					 integers.add(nums[k]);
    					 res.add(integers);
    				}
    			}
    		}
    	}
    	return res;
    }
    
    /**
    *  解法2:先排序,目的是为了去重,
    *  利用键值记录可以直接判断第三个数是否已存在,这样的话就不需要再对剩余的数据逐个判断,少了一个计算量级
    *  时间复杂度:O(n^2)
    *  空间复杂度:O(n)
    */
    public List<List<Integer>> threeSum(int[] nums) {
    	if(nums== null || nums.length==0){
    		return new ArrayList<>();
    	}
    	Arrays.sort(nums);
    	Map<Integer,Integer> map = new HashMap<>();
    	for (int i = 0; i < nums.length; i++) {
    		map.put(nums[i], i);
    	}
    
    	List<List<Integer>> res = new ArrayList<>();
    	for (int i = 0; i < nums.length; i++) {
    		if(i>0 && nums[i]== nums[i-1]) continue;  // 排序后对比是为了去重
    		for (int j = i+1; j <nums.length ; j++) {
    			if(j>i+1 && nums[j]== nums[j-1]) continue;
    			int a = nums[i];
    			int b = nums[j];
    			int c = -a-b;
    
    			if(map.containsKey(c) && map.get(c) > j){       // > j目的是去重
    				List<Integer> integers = new ArrayList<>();
    				integers.add(a);
    				integers.add(b);
    				integers.add(c);
    				res.add(integers);
    			}
    		}
    	}
    	return res;
    }
    
    /**
     * 解法3: 先对元素进行排序(快排)固定某元素num[i],在其后面的一组元素中从两端选择两个元素,
     * 如果元素num[i]大于0,则其后的所有元素都>0,不可能存在一组3个元素之和等于0
     * 如果num[i]和选择的两个元素num[L],num[R] 之和小于0,则L++
     * 如果num[i]和选择的两个元素num[L],num[R] 之和大于0,则R--
     */
    public List<List<Integer>> threeSum(int[] nums) {
    	if(nums== null || nums.length==0){
    		return new ArrayList<>();
    	}
    	// 底层用的快排
    	Arrays.sort(nums);
    	Map<Integer,Integer> map = new HashMap<>();
    	for (int i = 0; i < nums.length; i++) {
    		map.put(nums[i], i);
    	}
    	List<List<Integer>> res = new ArrayList<>();
    	int len = nums.length;
    
    	for (int i = 0; i < len; i++) {
    
    		if(nums[i]>0) break;
    		if((i>0) && (nums[i]== nums[i-1])) continue;    // 去重
    		int L = i+1,R = len-1;
    		while (L < R){
    			int count = nums[i] + nums[L] + nums[R];
    			if(count == 0){
    				List<Integer> integers = new ArrayList<>();
    				integers.add(nums[i]);
    				integers.add(nums[L]);
    				integers.add(nums[R]);
    				res.add(integers);
    
    				// 去重复
                    while (L < R && nums[L] == nums[L + 1]) L++;
                    while (L < R && nums[R] == nums[R - 1]) R--;
    				L++;
    				R--;
    			}
    			if(count < 0) L++;
    			if(count > 0) R--;
    		}
    	}
    
    	return res;
    }
    
  • 相关阅读:
    js-js系列-数据类型-概念
    js-基础总结3
    js-基础总结2
    js-基础总结1
    js-面试题
    webpack-模块化
    js-对象常用方法
    js-事件冒泡-事件捕获-事件委托
    js-call aplly bind2
    aioxs实现token无感刷新
  • 原文地址:https://www.cnblogs.com/fyusac/p/13121069.html
Copyright © 2011-2022 走看看