• 微软面试题: 15. 三数之和 出现次数:3


    题目描述:

      给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?

    请你找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组。

    思路分析:

      排序 + 双指针 ,本题考察的重难点在于如何去除重复解。算法流程如下:

    1. 特判,对于数组长度 n,如果数组为 null 或者数组长度小于 3,返回 []

    2. 对数组进行排序。

    3.  遍历排序后数组。 

           3.1  若 nums[i] > 0  :因为数组已经排序好,所以后面两个数也是正的 ,不可能有三个数加和等于 0

    直接返回结果。

      3.2   对于重复元素:跳过,避免出现重复解。三个数遇到重复元素都要跳过。

          3.3   令左指针 L=i+1L=i+1,右指针 R=n-1R=n1,当 L<RL<R 时,执行循环:

          *  当 nums[i]+nums[L]+nums[R]==0nums[i]+nums[L]+nums[R]==0,执行循环,判断左界和右界

                  是否和下一位置重复,去除重复解。并同时将 L,RL,R 移到下一位置,寻找新的解。      

                     *   若和大于 0,说明 nums[R]   太大,R左移;

                     *    若和小于 0,说明 nums[L] 太小,L右移;

    代码如下:

     1 class Solution {
     2 public:
     3     vector<vector<int>> threeSum(vector<int>& nums)
     4     {
     5         if(nums.size() < 3) return {};
     6         vector<vector<int>> res;
     7          
     8         const int len = nums.size();
     9         std::sort(nums.begin(),nums.end());
    10         if(nums[0] > 0) return {};
    11         for(int i = 0;i < len - 2;++i)
    12         {
    13             if(nums[i] > 0)
    14             {
    15                 return res;
    16             }
    17             int l = i + 1;
    18             int h = len - 1;
    19             while(l < h)
    20             {
    21                 long int sum = nums[i] + nums[l] + nums[h];//注意整数避免溢出
    22                 if(sum == 0)
    23                 {
    24                     vector<int> triple(3,0);
    25                     triple[0] = nums[i];
    26                     triple[1] = nums[l];
    27                     triple[2] = nums[h];
    28                     res.push_back(triple);
    29                     
    30                      while(l+1<h && nums[l] == nums[l+1]) l++; //避免nums[l]作为第二个数重复出现
    31                      while( h-1 >l && nums[h-1] == nums[h]) h--;//避免nums[l]作为第三个数重复出现
    32                      l++;
    33                      h--;
    34                 }
    35                 else if(sum > 0)
    36                 {
    37                     --h;
    38                 }
    39                 else 
    40                 {
    41                     ++l;
    42                 }
    43             }
    44         //避免nums[i]作为第一个数重复出现
    45           while(i+1 < len - 2 && nums[i] == nums[i+1]) i++; 
    46         }
    47         return res;
    48     }
    49 };

     

  • 相关阅读:
    递归斐波那契数列时间复杂度
    动态规划 矩阵链乘法
    kmp算法
    贪心 单源最短路径
    贪心法 背包问题求解
    贪心法 货币支付问题或找零问题
    贪心算法简介
    排列问题的递归算法和非递归算法
    php __set() __get() __isset() __unset()四个方法的应用
    使用栈结构完毕四则运算
  • 原文地址:https://www.cnblogs.com/wangxf2019/p/13992127.html
Copyright © 2020-2023  润新知