zoukankan      html  css  js  c++  java
  • leetcode 15.三数之和

    题目描述:

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

    注意:答案中不可以包含重复的三元组。

    例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

    满足要求的三元组集合为:
    [
    [-1, 0, 1],
    [-1, -1, 2]
    ]

    思路分析:

    面试中常常出现的3sum问题,和2sum是比较类似的。但这里由于是三个数的和为0,因此首先需要固定一个数,再在其后续的序列中利用2sum的方法。由于题目要求不可包含重复的三元组,因此需要进行一些过滤。首先对数组进行排序,判断当前元素是否大于0,若大于0,则不可能与后续的元素组成三元组,直接退出。若当前的元素与前一个元素相等,表示重复,跳过本轮循环。此外,在twoSum函数中,也需要进行判断,若当前left值与前一位相等,则重复,跳过;同理当前right值与后一位相等,则重复,跳过。算法复杂度为O(n^2)。

    代码:

     1 class Solution {
     2 public:
     3     void twoSum(vector<vector<int>>&res, vector<int>& nums, int cur)
     4     {
     5         int left = cur+1;
     6         int right = nums.size()-1;
     7         while(left<right && left>cur && right<nums.size())
     8         {
     9             int sum = nums[left]+nums[cur]+nums[right];
    10             if(sum > 0)
    11                 right--;
    12             else if(sum < 0)
    13                 left++;
    14             else
    15             {
    16                 if(left==cur+1 || right==nums.size()-1)
    17                 {
    18                     res.push_back(vector<int>{nums[cur], nums[left], nums[right]});
    19                     left++;
    20                     right--;
    21                 }
    22                 else if(nums[left]==nums[left-1])
    23                     left++;
    24                 else if(nums[right] == nums[right+1])
    25                     right--;
    26                 else
    27                 {
    28                     res.push_back(vector<int>{nums[cur], nums[left], nums[right]});
    29                     left++;
    30                     right--;
    31                 }
    32             }
    33         }
    34     }
    35     vector<vector<int>> threeSum(vector<int>& nums) {
    36         vector<vector<int>> res;
    37         if(nums.size()<3)
    38             return res;
    39         sort(nums.begin(), nums.end());
    40         for(int i=0; i<nums.size(); i++)
    41         {
    42             if(nums[i]>0)
    43                 break;
    44             if(i>0 && nums[i]==nums[i-1])
    45                 continue;
    46             twoSum(res, nums, i);
    47         }
    48         return res;
    49     }
    50 };
  • 相关阅读:
    从构建分布式秒杀系统聊聊限流特技
    轻快的VIM(三):删除
    shell中各种括号的作用()、(())、[]、[[]]、{}
    java的重写规则
    UNIX命令,统计当前目录(含子目录)下所有后缀为.log的文件中ERROR出现的行数
    linux下使用 du查看某个文件或目录占用磁盘空间的大小
    linux如何查看系统占用磁盘空间最大的文件及让文件按大小排序
    管道命令和xargs的区别(经典解释)
    JAVA 一个或多个空格分割字符串
    shell替换一个或多个空格为逗号
  • 原文地址:https://www.cnblogs.com/LJ-LJ/p/11317535.html
Copyright © 2011-2022 走看看