微软面试题: 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 };

 

原文地址:https://www.cnblogs.com/wangxf2019/p/13992127.html