• 【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输出
        }
    };
     
  • 相关阅读:
    LaTeX入门
    用jdom来解析xml文件小Demo
    Java乔晓松基于注解的面向AOP(切面)编程
    三层架构实战篇—系统登录实例
    selenium ide插件介绍
    WPF17行为(以控件在界面拖动为例)
    火狐浏览器显示“已阻止载入混合活动内容“的解决方法
    博客园—打赏功能
    网页返回顶部的几种方法
    自定义美化博客园
  • 原文地址:https://www.cnblogs.com/wikiwen/p/10224242.html
Copyright © 2020-2023  润新知