码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode015--三数之和

时间:2020-10-08 19:39:17      阅读:14      评论:0      收藏:0      [点我收藏+]

标签:static   imp   port   size   system   new   ati   hash   alt   

三数之和--LeetCode015

题目描述:

技术图片

知识点:哈希表,对撞双指针

三重循环遍历nums数组。时间复杂度是O(n ^ 3),其中n为数组nums的长度。空间复杂度是O(1)。

JAVA代码:

package com.zhizhu.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {

    public static List<List<Integer>> threeSum(int[] nums) {
        int n = nums.length;
        List<List<Integer>> listList = new ArrayList<>();
        Arrays.sort(nums);

        for (int i = 0; i < n; i++) {
            if (nums[i] > 0) {
                break;
            }
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

            for (int j = i + 1; j < n; j++) {
                if (nums[i] + nums[j] > 0) {
                    break;
                }

                if (j > i + 1 && nums[j] == nums[j - 1]) {
                    continue;
                }

                for (int k = j + 1; k < n; k++) {
                    if (nums[i] + nums[j] + nums[k] > 0) {
                        break;

                    }

                    if (k > j + 1 && nums[k] == nums[k - 1]) {
                        continue;
                    }

                    if (nums[i] + nums[j] + nums[k] == 0) {
                        List<Integer> list = new ArrayList<>();
                        list.add(nums[i]);
                        list.add(nums[j]);

                        list.add(nums[k]);

                        listList.add(list);

                    }

                }

            }

        }

        return listList;


    }


}

测试代码:

package com.m.lc_threenum;


public class Test1 {
    public static void main(String[] args) {

        int [] arr = new int[]{-1, 0, 1, 2, -1, 4};
        Solution1 solution1 = new Solution1();
        System.out.println(solution1.threeSum(arr));    //  [[-1, -1, 2], [-1, 0, 1]]

    }
}

思路二:用一个哈希表来存储数组中的所有元素及其出现的次数

我们用一个哈希表来存储数组中出现的所有元素及其出现的次数。

我们总共分三种情况:

(1)三个数字相同:如果0这个数字在哈希表中记录的次数等于或者大于3次,那么3个0是一个组合,将其记录在结果中。

(2)两个数字相同:在我们用哈希表记录了数组中所有元素及其出现的次数以后,我们就可以对数组进行过滤,将重复的元素剔除掉得到一个新的数组集合ArrayList,里面没有重复元素。对这个集合进行一次排序操作。再用双重循环遍历集合。

a.当arrayList.get(i) * 2 + arrayList.get(j) == 0且在哈希表中arrayList.get(i)出现的次数大于等于2次。

b.当arrayList.get(i) + arrayList.get(j) * 2 == 0且在哈希表中arrayList.get(j)出现的次数大于等于2次。

(3)三个数字都不同:在哈希表中- arrayList.get(i) - arrayList.get(j)出现的次数大于等于1次且- arrayList.get(i) - arrayList.get(j) > arrayList.get(j)。

将上述三种情况的结果都保存在结果中,最终返回总结果即可。

这个思路过程中生成哈希表这一过程的时间复杂度是O(n),其中n为数组的长度。排序arrayList集合的时间复杂度是O(mlogm),其中m为数组中不重复元素的个数。遍历arrayList的时间复杂度是O(m ^ 2)。而空间复杂度由于使用了哈希表,一定是O(n)级别的。

JAVA代码:

package com.m.lc_threenum.solution2;


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

public class Solution2 {


    public List<List<Integer>> threeSum(int[] nums) {


        List<List<Integer>> listList = new ArrayList<>();


        HashMap<Integer, Integer> hashMap = new HashMap<>();


        for (int i = 0; i < nums.length; i++) {
            if (hashMap.containsKey(nums[i])) {
                hashMap.put(nums[i], hashMap.get(nums[i]) + 1);

            } else {
                hashMap.put(nums[i], 1);

            }

        }


        if (hashMap.containsKey(0) && hashMap.get(0) >= 3) {
            addToListList(0, 0, 0, listList);
        }

        ArrayList<Integer> arrayList = new ArrayList<>();

        for (Integer integer : hashMap.keySet()) {

            arrayList.add(integer);

        }


        Collections.sort(arrayList);


        for (int i = 0; i < arrayList.size(); i++) {


            for (int j = i + 1; j < arrayList.size(); j++) {


                if (arrayList.get(i) * 2 + arrayList.get(j) == 0 && hashMap.get(arrayList.get(i)) >= 2) {


                    addToListList(arrayList.get(i), arrayList.get(i), arrayList.get(j), listList);

                }

                if (arrayList.get(i) + arrayList.get(j) * 2 == 0 && hashMap.get(arrayList.get(j)) >= 2) {


                    addToListList(arrayList.get(i), arrayList.get(j), arrayList.get(j), listList);


                }


                int num = -arrayList.get(i) - arrayList.get(j);


                if (num > arrayList.get(j) && hashMap.containsKey(num)) {


                    addToListList(arrayList.get(i), arrayList.get(j), num, listList);


                }


            }


        }


        return listList;


    }


    private void addToListList(int num1, int num2, int num3, List<List<Integer>> listList) {

        List<Integer> list = new ArrayList<>();

        list.add(num1);

        list.add(num2);

        list.add(num3);

        listList.add(list);


    }


}

测试代码:

package com.m.lc_threenum.solution2;

public class Test2 {
    public static void main(String[] args) {
        int [] arr = new int[]{-1, 0, 1, 2, -1, 4};
        Solution2 solution2 = new Solution2();
        System.out.println(solution2.threeSum(arr));    //  [[-1, -1, 2], [-1, 0, 1]]
    }
}

LeetCode015--三数之和

标签:static   imp   port   size   system   new   ati   hash   alt   

原文地址:https://www.cnblogs.com/k-class/p/13781145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!