亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++實現LeetCode(15.三數之和)

 更新時間:2021年07月13日 09:12:01   作者:Grandyang  
這篇文章主要介紹了C++實現LeetCode(三數之和),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下

[LeetCode] 15. 3Sum 三數之和

Given an array S of n integers, are there elements abc in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
  • The solution set must not contain duplicate triplets.

    For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
(-1, 0, 1)
(-1, -1, 2)

這道題讓我們求三數之和,比之前那道 Two Sum 要復雜一些,博主考慮過先 fix 一個數,然后另外兩個數使用 Two Sum 那種 HashMap 的解法,但是會有重復結果出現,就算使用 TreeSet 來去除重復也不行,會 TLE,看來此題并不是考 Two Sum 的解法。來分析一下這道題的特點,要找出三個數且和為0,那么除了三個數全是0的情況之外,肯定會有負數和正數,還是要先 fix 一個數,然后去找另外兩個數,只要找到兩個數且和為第一個 fix 數的相反數就行了,既然另外兩個數不能使用 Two Sum 的那種解法來找,如何能更有效的定位呢?我們肯定不希望遍歷所有兩個數的組合吧,所以如果數組是有序的,那么就可以用雙指針以線性時間復雜度來遍歷所有滿足題意的兩個數組合。

對原數組進行排序,然后開始遍歷排序后的數組,這里注意不是遍歷到最后一個停止,而是到倒數第三個就可以了。這里可以先做個剪枝優(yōu)化,就是當遍歷到正數的時候就 break,為啥呢,因為數組現在是有序的了,如果第一個要 fix 的數就是正數了,則后面的數字就都是正數,就永遠不會出現和為0的情況了。然后還要加上重復就跳過的處理,處理方法是從第二個數開始,如果和前面的數字相等,就跳過,因為不想把相同的數字fix兩次。對于遍歷到的數,用0減去這個 fix 的數得到一個 target,然后只需要再之后找到兩個數之和等于 target 即可。用兩個指針分別指向 fix 數字之后開始的數組首尾兩個數,如果兩個數和正好為 target,則將這兩個數和 fix 的數一起存入結果中。然后就是跳過重復數字的步驟了,兩個指針都需要檢測重復數字。如果兩數之和小于 target,則將左邊那個指針i右移一位,使得指向的數字增大一些。同理,如果兩數之和大于 target,則將右邊那個指針j左移一位,使得指向的數字減小一些,代碼如下:

解法一:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        if (nums.empty() || nums.back() < 0 || nums.front() > 0) return {};
        for (int k = 0; k < (int)nums.size() - 2; ++k) {
            if (nums[k] > 0) break;
            if (k > 0 && nums[k] == nums[k - 1]) continue;
            int target = 0 - nums[k], i = k + 1, j = (int)nums.size() - 1;
            while (i < j) {
                if (nums[i] + nums[j] == target) {
                    res.push_back({nums[k], nums[i], nums[j]});
                    while (i < j && nums[i] == nums[i + 1]) ++i;
                    while (i < j && nums[j] == nums[j - 1]) --j;
                    ++i; --j;
                } else if (nums[i] + nums[j] < target) ++i;
                else --j;
            }
        }
        return res;
    }
};

或者我們也可以利用 TreeSet 的不能包含重復項的特點來防止重復項的產生,那么就不需要檢測數字是否被 fix 過兩次,不過個人覺得還是前面那種解法更好一些,參見代碼如下:

解法二:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        set<vector<int>> res;
        sort(nums.begin(), nums.end());
        if (nums.empty() || nums.back() < 0 || nums.front() > 0) return {};
        for (int k = 0; k < (int)nums.size() - 2; ++k) {
            if (nums[k] > 0) break;
            int target = 0 - nums[k], i = k + 1, j = (int)nums.size() - 1;
            while (i < j) {
                if (nums[i] + nums[j] == target) {
                    res.insert({nums[k], nums[i], nums[j]});
                    while (i < j && nums[i] == nums[i + 1]) ++i;
                    while (i < j && nums[j] == nums[j - 1]) --j;
                    ++i; --j;
                } else if (nums[i] + nums[j] < target) ++i;
                else --j;
            }
        }
        return vector<vector<int>>(res.begin(), res.end());
    }
};

到此這篇關于python實現LeetCode(三數之和)的文章就介紹到這了,更多相關python實現三數之和內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++中將Char轉換成String的4種方法

    C++中將Char轉換成String的4種方法

    本文主要介紹了C++中將Char轉換成String的4種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • java string對象上的操作,常見的用法你知道嗎

    java string對象上的操作,常見的用法你知道嗎

    今天給大家?guī)淼氖顷P于Java的相關知識,文章圍繞著Java String類用法展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-08-08
  • C語言在輸入輸出時遇到的常見問題總結

    C語言在輸入輸出時遇到的常見問題總結

    大家在平時的做題中是否會遇到和我一樣的煩惱,題目的代碼已經基本完成,但是在輸出時候,總是和題目給出的樣例輸出格式不同?,導致題目不能通過。為了解決這一煩惱,我總結了以下幾點,需要的可以參考一下
    2022-09-09
  • C++繼承中的對象構造與析構和賦值重載詳解

    C++繼承中的對象構造與析構和賦值重載詳解

    這篇文章主要為大家詳細介紹了C++繼承中的對象構造與析構和賦值重載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++實現LeetCode(174.地牢游戲)

    C++實現LeetCode(174.地牢游戲)

    這篇文章主要介紹了C++實現LeetCode(174.地牢游戲),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • c++運算符重載基礎知識詳解

    c++運算符重載基礎知識詳解

    運算符重載是一種形式的C++多態(tài)。運算符重載將重載的概念擴展到運算符上,允許賦予C++運算符多種含義
    2014-03-03
  • C++中的幾個特殊符號說明

    C++中的幾個特殊符號說明

    這篇文章主要介紹了C++中的幾個特殊符號說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++ txt 文件讀取,并寫入結構體中的操作

    C++ txt 文件讀取,并寫入結構體中的操作

    這篇文章主要介紹了C++ txt 文件讀取,并寫入結構體中的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • C++ 關于 CMFCPropertyGridCtrl 的使用方法

    C++ 關于 CMFCPropertyGridCtrl 的使用方法

    這篇文章主要介紹了C++ 關于 CMFCPropertyGridCtrl 的使用方法的相關資料,需要的朋友可以參考下
    2015-06-06
  • c++查詢最短路徑示例

    c++查詢最短路徑示例

    這篇文章主要介紹了c++查詢最短路徑示例,需要的朋友可以參考下
    2014-05-05

最新評論