zoukankan      html  css  js  c++  java
  • LeetCode 15. 3Sum

    问题链接

    LeetCode 15. 3Sum

    题目解析

    给定n个元素的数组,寻找符合 (a+b+c=0) 的所有 {a, b, c}。

    解题思路

    如果对LeetCode的第一题Two Sum 还有印象的话,会发现这道题很类似,不过题目要求的结果有明显区别,本题需要求出所有符合条件的结果。

    如果想复用Two Sum中的方法,可以加以转化:(a+b = -c),与 (x+y = target)就很类似了。存在一个严重的问题——重复的结果!为了避免重复,可以想到需用使用 (set) 容器。由于 (set) 中的元素是三元素向量,想要避免重复必须使向量中三个元素有序,所以需要先将数组排序。

    参考代码

    class Solution {
    public:
        vector<vector<int>> threeSum(vector<int>& nums) {
            set<vector<int>> res;
            sort(nums.begin(), nums.end());
            for (int k = 0; k < nums.size(); k++) {
                if (nums[k] > 0) break;
                
                int target = 0 - nums[k];//固定最小数
                int i = k + 1, j = nums.size() - 1;
                while (i < j) {
                    if (nums[i] + nums[j] < target) ++i;
                    else if (nums[i] + nums[j] > target) --j;
                    else {
                        res.insert({nums[k], nums[i], nums[j]});
                        ++i; --j;
                    }
                }
            }
            return vector<vector<int>>(res.begin(), res.end());
        }
    };
    

    方法改进

    上述代码需要300+ms,太慢了,仔细想想,其实不用 (set) 容器也可以做到,先将数组排序,遍历每个数字,即先确定最小的数字,寻找另外两个数,避免重复只需要跳过相等的数字(位于相邻位置)即可。思路一模一样,这其实是对上一方法的简化,因为二者都需要排序,而排好序后相等的数字必然在相邻位置,开直接排序,不需要 (set)。这种改进方法只要100+ms,快了不止一点点~

    参考代码

    class Solution {
    public:
        vector<vector<int>> threeSum(vector<int>& nums) {
            vector<vector<int>> res;
            sort(nums.begin(), nums.end());
            for (int k = 0; k < nums.size(); k++) {
                if (nums[k] > 0) break;
                if (k > 0 && nums[k] == nums[k - 1])//避免重复
                    continue;
                
                int target = 0 - nums[k];//固定最小数
                int i = k + 1, j = nums.size() - 1;
                while (i < j) {
                    if (nums[i] + nums[j] < target) ++i;
                    else if (nums[i] + nums[j] > target) --j;
                    else {
                        res.push_back({nums[k], nums[i], nums[j]});
                        while (i < j && nums[i] == nums[i + 1])//避免重复
                            ++i;
                        while (i < j && nums[j] == nums[j - 1])//避免重复
                            --j;
                        ++i; --j;
                    }
                }
            }
            return res;
        }
    };
    

    相似题目

    LeetCode 1. Two Sum
    LeetCode 16. 3Sum Closest
    LeetCode 18. 4Sum


    LeetCode All in One题解汇总(持续更新中...)

    本文版权归作者AlvinZH和博客园所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.


  • 相关阅读:
    索引的结构和性能的关系
    TP5的多图上传
    TP5页面更改数字进行AJAX排序
    安装Git版本控制系统 以及Git Bash的基础命令
    tp5 前台 点击显示一个弹窗
    Tp5 (轮回) 多个富文本应用
    Tp5 (轮回) AJAX请求写搜索页面
    安装 SVN 服务器
    Tp5(轮回)------单图上传 运用AJAX 请求
    TP5中(通过一个表去取另一个表的相对应的名称)
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/8602442.html
Copyright © 2011-2022 走看看