• [Leetcode]4Sum随记


    No.18, 4Sum

    给定一个数字数组,找出所有四个数字加和等于target的组合。要求输出中不含重复的组合,以及组合中的数字按照从小到大升序排列。

    前面做过2Sum,3Sum,这次是4Sum。其实KSum的都可以采用3Sum类似的方法来做,先把数组排序,再定死k-2个数字(即外面有k-2重循环),利用头尾两个指针查找余下的数组中合适的组合,如果比target小,则左指针++,如果比target大,则右指针--。采用这种方法做一般复杂度都是O(nk-1)。当然这里还需要注意处理数组中有重复的情况,需要每一次循环的时候判断是否重复。

    public class Solution {
        public List<List<Integer>> fourSum(int[] nums, int target) {
            List result=new ArrayList<List<Integer>>();
            if(nums.length<4){
                return result;
            }
            Arrays.sort(nums);
            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 begin=j+1;
                    int end=nums.length-1;
                    while(begin<end){
                        if(begin>j+1&&nums[begin]==nums[begin-1]){
                            begin++;
                            continue;
                        }
                        int t=nums[i]+nums[j]+nums[begin]+nums[end];
                        if(t==target){
                            List<Integer> list=new ArrayList<Integer>();
                            list.add(nums[i]);
                            list.add(nums[j]);
                            list.add(nums[begin]);
                            list.add(nums[end]);
                            Collections.sort(list);
                            result.add(list);
                            begin++;
                            end--;
                        }
                        else if(t<target){
                            begin++;
                        }
                        else{
                            end--;
                        }
                    }
                }
            }
            return result;
        }
    }

    另外针对4Sum还想了一种方法。将数组中的数字两两搭对,算出它们的和,使用map记录该值以及该数字对,map的value使用list数据结构,这样可以记录多个和相同的数字对。遍历map,查找加和为target的map key,再将其中的数字对组合。看起来比较简单,但是这样做还需要注意的一点,pair1和pair2组合的时候,可能同一个数字同时存在于两个地方,那么这样得到的组合事实上是不存在的,可以在开始计算pair的时候,记录每一个数字出现的次数,再验证结果是否妇存在。下面贴的是这种方法的核心代码,但是我没有处理上述注意的地方,因此结果不正确,仅供参考。

        public List<List<Integer>> fourSum(int[] nums, int target) {
            List result=new ArrayList<List<Integer>>();
            Arrays.sort(nums);
            HashMap map=new HashMap<Integer,List<List<Integer>>>();
            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>0&&nums[j]==nums[j-1]){
                        continue;
                    }
                    int add=nums[i]+nums[j];
                    List<Integer> pair=new ArrayList<Integer>();
                    pair.add(nums[i]);
                    pair.add(nums[j]);
                    List list=(List) map.get(add);
                    if(list==null){
                        list=new ArrayList<List<Integer>>();
                        map.put(add, list);
                    }
                    list.add(pair);
                }
            }
            Iterator it=map.entrySet().iterator();
            while(it.hasNext()){
                Entry entry=(Entry) it.next();
                int key=(int) entry.getKey();
                if(key>=target-key){
                    continue;
                }
                List<List<Integer>> pair1=(List<List<Integer>>)entry.getValue();
                List<List<Integer>> pair2=(List<List<Integer>>) map.get(target-key);
                if(pair2!=null){
                    for(int i=0;i<pair1.size();i++){
                        for(int j=0;j<pair2.size();j++){
                            List<Integer> list=new ArrayList<Integer>();
                            list.add(pair1.get(i).get(0));
                            list.add(pair1.get(i).get(1));
                            list.add(pair2.get(j).get(0));
                            list.add(pair2.get(j).get(1));
                            Collections.sort(list);
                            if(!result.contains(list)){
                                result.add(list);
                            }                       
                        }
                    }             
                }
            }
            return result;
        }
    View Code
  • 相关阅读:
    面试系统化学习和准备(一)——今日事必须今日毕
    20220324准备
    面试系统化学习和准备(二)——docker篇
    20220325目标
    任务调度系统
    二叉树最大路径和
    count(*)这么慢,我该怎么办?
    动态规划最长连续递增序列
    设置工作模式与环境(上):建立计算机
    Django 数据库配置(二)
  • 原文地址:https://www.cnblogs.com/lilylee/p/5228632.html
Copyright © 2020-2023  润新知