1. 程式人生 > >leedcode第15題三數之和詳解

leedcode第15題三數之和詳解

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;





}