zoukankan      html  css  js  c++  java
  • 【LeetCode & 剑指offer刷题】数组题3:3Sum(系列) + 4sum

    【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

    3Sum

    Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
    Note:
    The solution set must not contain duplicate triplets.
    Example:
    Given array nums = [-1, 0, 1, 2, -1, -4],
     
    A solution set is:
    [
    [-1, 0, 1],
    [-1, -1, 2]
    ]

    C++
     
    //问题:找数组中和为0的三元组
    //方法:排序后,扫描数组,转化为2sum问题
    //2sum对应一个循环,3sum对应两重循环,4sum对应三重循环
    //O(n^2)
    #include <algorithm>
    class Solution
    {
    public:
        vector<vector<int>> threeSum(vector<int>& a)
        {
            vector<vector<int>> res;
            int n = a.size();
            if(n<3) return res;
           
            sort(a.begin(), a.end()); //排序
     
            //扫描a[i],后面在用leftright首尾两指针扫描
            for(int i = 0; i<n && a[i]<=0; i++) //第一个数只能是负数或0,加此判断以节省时间,如果不加次判断,则i<n-2即可
            {
                int target = -a[i]; //将第一个数的相反数定为2sum的target 
                int left = i+1//i=0~n-3
                int right = n-1;
     
                while(left < right) //用两个指针分别从a[i+1]和整个数组末尾开始向中间扫描 ,找到所有可以满足和为-a[i]的数对
                {
                    int sum = a[left] + a[right];
                    if(sum < target) left++; //仅移动前面指针
                    else if(sum > target) right--; //仅移动后面指针
                    else //满足3sum要求
                    {
                        res.push_back({a[i], a[left], a[right]});  //将满足的三元组push到结果向量中(也可以用vector<int>{a[i], a[left], a[right]})
     
                        while(left<right && a[left+1] == a[left]) left++; //以免第二个数重复
                        while(left<right && a[right-1] == a[right]) right--;//以免第三个数重复
                        left++; //前后指针都移动,下一次判断
                        right--;
                    }
                }
                while(i+1 < n && a[i+1] == a[i]) i++; //以免第一个数重复
            }
           
            return res;
        }
    };
    /*注:
    也可用set避免重复
    set<vector<int>> res;
    ...
    vector<vector<int>>(res.begin(), res.end());//用迭代器将set转为vector
    */
     
    16. 3Sum Closest
    Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
    Example:
    Given array nums = [-1, 2, 1, -4], and target = 1.
     
    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

     
    /*
    问题:离目标值最近的三数之和
    方法:排序后,扫描a[i],后面在用leftright首尾两指针扫描
    */
    class Solution
    {
    public:
        int threeSumClosest(vector<int>& nums, int target)
        {
            if(nums.size()<3) return 0;
           
            int closest = nums[0] + nums[1] + nums[2];
            int diff = abs(closest - target);
            sort(nums.begin(), nums.end()); //排序
           
            //扫描a[i],后面在用leftright首尾两指针扫描
            for (int i = 0; i < nums.size() - 2; i++)  //i=0~n-3(n-2,n-1分别为leftright占着)
            {
                int left = i + 1, right = nums.size() - 1; // left = i+1, right=n-1
               
                while (left < right)
                {
                    int sum = nums[i] + nums[left] + nums[right];
                    int newDiff = abs(sum - target);
                    if (newDiff < diff ) //更新diffsum
                    {
                        diff = newDiff;
                        closest = sum;
                    }
                   
                    if (sum < target) left++; //调节指针
                    else right--;
                }
            }
            return closest;
        }
    };
     
    18. 4Sum
    Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
    Note:
    The solution set must not contain duplicate quadruplets.
    Example:
    Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
     
    A solution set is:
    [
    [-1, 0, 0, 1],
    [-2, -1, 1, 2],
    [-2, 0, 0, 2]
    ]

    Seen this question in a real interview before?  YesNo
     
     
    /*
    问题:找与目标值相等的4个数
    三重循环即可
    set可避免重复结果
    */
    class Solution
    {
    public:
        vector<vector<int>> fourSum(vector<int> &nums, int target)
        {
            if(nums.size() < 4) return vector<vector<int>>(); //或者用{{}}
           
            set<vector<int>> res;
            sort(nums.begin(), nums.end());
           
            //扫描a[i],a[j]后面接left,right两个指针
            for (int i = 0; i < int(nums.size() - 3); i++)
            {
                for (int j = i + 1; j < int(nums.size() - 2); j++)
                {
        //            if (j > i + 1 && nums[j] == nums[j - 1]) continue; //遇到重复数时不执行下面语句,如果用set可以不进行此判断
                   
                    int left = j + 1, right = nums.size() - 1//i=0~n-4,j=i+1~n-3
                    while (left < right)
                    {
                        int sum = nums[i] + nums[j] + nums[left] + nums[right];
                        if (sum == target)
                        {
                            vector<int> out{nums[i], nums[j], nums[left], nums[right]};
                            res.insert(out); //set,当有重复结果时,插入会失败
                            left++; right--;
                        }
                        else if (sum < target) left++;
                        else right--;
                    }
                }
            }
            return vector<vector<int>>(res.begin(), res.end()); //set转化为vector输出
        }
    };
     
  • 相关阅读:
    如何上传整个项目或者是文件夹到github
    阅读笔记16-架构师推荐:提高90%开发效率的工具推荐
    阅读笔记15-这些普通的程序猿,如今都已进阶成为技术大佬
    python爬虫——爬取淘票票正在热映电影
    阅读笔记12-Java 面试题 —— 老田的蚂蚁金服面试经历
    SOA架构设计案例分析
    阅读笔记11-孤独后厂村:30万互联网人跳不出的中国硅谷
    阅读笔记09-Java程序员必备的Intellij插件
    阅读笔记08-程序员依然是这个时代,贫寒学子翻身的不二选择
    os.path.join()
  • 原文地址:https://www.cnblogs.com/wikiwen/p/10224242.html
Copyright © 2011-2022 走看看