07 - leedcode第15题三数之和详解——基于c++

vector<vector<int>> leedcode15::easy_threeSum(vector<int>& nums)
{
    /**
     * 巧妙解法:其中有一些剪枝优化的思想
     * 1、先对给定的数组进行从小到大排序
     * 如:   1, 2, -1, -3, 0, 3
     * 排序:-3, -1, 0, 1, 2, 3
     * 2、从排序后数组中第一个元素开始固定,
     *如固定-3,然后设置一个指针p1指向-1,设置另一个指针p2指向3。
     * 1)若*p1 + *p2 = 3,则返回这三个数值,然后两个指针同时移动,
     *若只移动一个指针,结果必定是重复的三个数值,或者不相等。
     * 2)若*p1 + *p2 < 3, 则将p1指针向右移动,若*p1 + *p2 > 3则反之。
     * 3)注意:若指针移动后的值与没有移动的值相同,则要跳过。
     * 依次固定直到固定的元素大于0
     */
     //0 0 0 0 0 0 0 0 0
     //0 1 2 3 4 5 6 7 8
     //-5 -5 -4 -4 -4 -2 -2 -2 0 0 0 1 1 3 4 4
     //vector<int> vec_result;
     vector<vector<int>> result;         //设置一个容器的容器用来盛放结果
     if (nums.size() < 3) return result; //非常重要的代码,边界条件传入数组小于3则直接返回
     sort(nums.begin(), nums.end());     //对传入的容器内的元素进行排序。
     //for(int i = 0; i < nums.size(); i++)
     int i = 0;                          //固定第一个元素
     while(i != nums.size() - 2)         //固定第一个元素,开始总循环,直到固定到倒数第三个元素
     {
         /**
          *总循环的第一步判断:
          * 1)i > 0:这里固定的第一个元素无需与前一个固定元素进行判断相等
          * 2)nums[i] == nums[i - 1]:固定的后一个元素与前一个元素相等,则跳过
          */
         if(i > 0 && (nums[i] == nums[i - 1])) i++; 
         /**
          *若总循环不需要跳过,则执行具体的比较代码
          */
         else
         {    
             if(nums[i] > 0) break;      //若固定的元素大于0,则直接结束本次循环
             int target = 0 - nums[i];   //设置固定元素的相反数
             if(nums[i] <= 0)            //若固定元素小于0,则执行具体代码
             {
                 int m = i + 1;          //设置指针m,指向固定元素的后面一位元素
                 int n = nums.size() - 1;//设置指针n,指向最后一位元素
                 while(m < n)            //进行循环判断(只有m < n才能遍历所有)
                 {
                     if(nums[m] + nums[n] == target) //判断,若满足条件
                     {   /**
                          * 里层判断:1)m > 0, n < (nums.size() - 1)这是对固定元素的是否重复的判断
                          * 若两个指针均移动一位后,与之前两个元素都相等,则两个指针都要移动,
                          * 若只移动一个则一定不会满足相等条件,或者重复
                          */
                         if(m > 0 && nums[m] == nums[m - 1] && n < (nums.size() - 1) && nums[n] == nums[n + 1])
                         {
                             ++m;
                             --n;
                         }
                         else
                         {
                             //vec_result.insert(vec_result.begin(), nums[i]);
                             //vec_result.insert(vec_result.begin() + 1, nums[m]);
                             //vec_result.insert(vec_result.begin() + 2, nums[n]);
                             //vec_result.erase(vec_result.begin() + 3, vec_result.end());
                             result.push_back({nums[i], nums[m], nums[n]});
                             //vec_result.erase(vec_result.begin(), vec_result.end());
                             ++m;
                             --n;
                         }

                     }
                     if(nums[m] + nums[n] < target) ++m; //并列判断条件
                     if(nums[m] + nums[n] > target) --n; //并列判断条件 

                 }
             }
             i++; //移动固定元素
         }


     }
     //sort(result.begin(), result.end());
     //result.erase(unique(result.begin(), result.end()), result.end());
     return result;





}

猜你喜欢

转载自blog.csdn.net/wjh8925750/article/details/82811014
07