leetcode 15. 3Sum

這裏寫圖片描述

  這是leetcode裏面點贊數比較多的題,難度不大但是不知道技巧會覺得難以解決。題幹很簡潔,從一個數組中找出和爲0的三個元素,組成一個三元組,返回不重複的所有滿足條件的三元組。這裏有兩個問題需要解決,怎樣才能從無序的數組中找出滿足條件的三元組,怎樣才能保證它們不重複。查看這題的討論區(Discuss欄)後,贊同數最多的那條令我恍然大悟。

  從無序的數組中查找難度比較大,所以可以先將數組排序,形成增序數組,然後對於數組中的元素nums[i],假定它是滿足條件的三元組中最小的元素(i從0到nums.size()-3,因爲某個滿足條件的三元組中最小元素的元素在原數組中至多是第3大),則其他兩個元素之和應該是-nums[i]。在num[i]的右邊設置遊標lo爲i+1,hi爲nums.size()-1,如果nums[lo]和nums[hi]的和爲-nums[i],則找到了一個滿足條件的三元組,保存,然後lo減一,hi加一。如果nums[lo]+nums[hi]小於-nums[i],說明nums[lo]過小,則lo加一;否則nums[hi]過大,hi減一。

  爲了解決重複問題,在取最小元素的過程中,遇到nums[i]和它前一個元素值相等的情況,跳過nums[i]。當找到一個滿足條件的三元組,lo減一之後,遇到nums[lo]和它前一個元素相等,lo繼續加一,直到不等,hi同理。

  以下是實現代碼

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        if (nums.size() < 3)
            return result;
        sort(nums.begin(), nums.end());
        for (int i = 0; i < nums.size() - 2; i++) {
            if (i != 0) {
                if (nums[i] == nums[i - 1])
                    continue;
            }
            int twosum = 0 - nums[i];
            int lo = i + 1, hi = nums.size() - 1;
            while (lo < hi) {
                if (nums[lo] + nums[hi] == twosum) {
                    vector<int> vec;
                    vec.push_back(-twosum);
                    vec.push_back(nums[lo]);
                    vec.push_back(nums[hi]);
                    result.push_back(vec);
                    lo++;
                    hi--;
                    while ((lo < hi)&&(nums[lo] == nums[lo - 1])) 
                        lo++;
                    while ((lo < hi)&&(nums[hi] == nums[hi + 1]))
                        hi--;
                } else {
                    if (nums[lo] + nums[hi] < twosum) {
                        lo++;
                    } else {
                        hi--;
                    }
                }
            }
        }
        return result;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章