• 【每日一题-leetcode】15.three sum


    15.三数之和

    给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

    注意:答案中不可以包含重复的三元组。

    示例:

    给定数组 nums = [-1, 0, 1, 2, -1, -4],

    满足要求的三元组集合为:[ [-1, 0, 1], [-1, -1, 2]]

    1.暴力求解

    thinking:通过三层loop 这里如果使用ArrryList 是有序 可重复,不能避免元素重复问题。但是使用

    LikedHashSet就可以避免元素重复问题

    时间复杂度:O(n^3)

    public List<List<Integer>> threeSum(int[] nums) {
           if(nums == null || nums.length <=2){
               return Collections.emptyList();
           }
    ​
           Arrays.sort(nums);
    ​
           Set<List<Integer>> result = new LinkedHashSet<>();
           for(int i=0;i<nums.length;i++){
               for(int j=i+1;j<nums.length;j++){
                   for(int k = j+1;k<nums.length;k++){
                       if(nums[i]+nums[j]+nums[k] == 0){
                           List<Integer> list = Arrays.asList(nums[i],nums[j],nums[k]);
                           result.add(list);
                       }
                   }
               }
           }
           return new ArrayList(result);
    }

    2.哈希表

    /**
        * hash slow
        * 1406 ms   46 MB
        *
        * @param nums
        * @return
        */
    private List<List<Integer>> hashSolution(int[] nums) {
        if (nums == null || nums.length <= 2) {
            return Collections.emptyList();
        }
        Set<List<Integer>> result = new LinkedHashSet<>();
    ​
        for (int i = 0; i < nums.length - 2; i++) {
            int target = -nums[i];
            Map<Integer, Integer> hashMap = new HashMap<>(nums.length - i);
            for (int j = i + 1; j < nums.length; j++) {
                int v = target - nums[j];
                Integer exist = hashMap.get(v);
                if (exist != null) {
                    List<Integer> list = Arrays.asList(nums[i], exist, nums[j]);
                    list.sort(Comparator.naturalOrder());
                    result.add(list);
                } else {
                    hashMap.put(nums[j], nums[j]);
                }
            }
        }
    ​
        return new ArrayList<>(result);
    }

    3.夹逼法

    thingking:左右夹逼,三数求和 a+b+c = 0 等价于 a+b=c 将数组进行排序,将c固定 a设置到c的下一个问题,也就是head b设置到最后一个位置 tail位置。

    第一次遍历c固定 head 和tail 分别向中间移动,判断如果-sum < target 说明值大 因为是负数。所以tail 左移动,否则就是head右移动。如此一轮后 如果找不到,接着c++ head 和tail接着判断。

    就可以找到。时间复杂度相对于上面两种是比较低的。

    时间复杂度:O(n)

    public List<List<Integer>> threeSum(int[] nums) {
            if (nums.length == 0 || nums.length <=2){
                return Collections.emptyList();
            }
    
            //元素去重
            Set<List<Integer>> result = new LinkedHashSet<>();
    
            //排序
            Arrays.sort(nums);
    
            for (int i = 0; i < nums.length-2; i++) {
                int head = i+1;//左端
                int tail = nums.length-1;//右端
                while (head<tail){
                    int sum = -(nums[head]+nums[tail]);//取负值
                    if (sum == nums[i]){
                        List<Integer> list = 			Arrays.asList(nums[i],nums[head],nums[tail]);
                        result.add(list);
                    }
                    if(sum<=nums[i]){
                        tail--;
                    }else {
                        head++;
                    }
                }
            }
            return new ArrayList<>(result);
        }
  • 相关阅读:
    前端开发之初探五
    前端开发之初探四
    前端开发之初探三
    漫谈
    前端工程师的发展之路
    SVG
    前端开发之初探一
    前端开发之初探二
    详解浏览器缓存
    webStroage案例
  • 原文地址:https://www.cnblogs.com/qxlxi/p/12860695.html
Copyright © 2020-2023  润新知