3Sum + 3SumClosest + 3SumSmaller

Vector : need skip repeat element using while, can extend to k-sum

(sort, 做 k-2 次循环, 从最内层循环左右夹逼,时间复杂度 O( max( nlog(n), n^(k-1) )

Set: if insert same element, skip automatically.

Sort, set to vector

Two pointers: 左右夹逼 :`j= i + 1; k = n - 1; j++, or k--, or j++; k--

3Sum

Bug: repeat elements
Input: [-2,0,0,2,2]
Output: [[-2,0,2],[-2,0,2]]
Expected: [[-2,0,2]]

solution 1: set

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        // bug: will insert same result
        //vector<vector<int> > res;
        set<vector<int> > res;


        int n = nums.size();
        if (n < 3) 
            return {};

        sort(nums.begin(), nums.end());

        for (int i = 0; i < n - 2; i++) {
            // !!! important tip!!!!!
            if (i == 0 || nums[i] != nums[i-1]) {

                int j = i + 1;
                int k = n - 1;
                while (j < k) {
                    int sum = nums[i] + nums[j] + nums[k];
                    if (sum == 0) {
                        //res.push_back( {nums[i], nums[j], nums[k]});
                        res.insert( {nums[i], nums[j], nums[k]});
                        j++;
                        k--;
                    } else if (sum < 0) {
                        j++;
                    } else {
                        k--;
                    }
                }

            }
        }

        for (vector<int> const &ve : res) {
        for (auto it : ve)  cout << it << ' ';

            cout << endl;
    }

        // convert set<vector<int> > to vector<vector<int> >  
        // way2: copy
        //vector<vector<int> > resv(res.size());
        //copy(res.begin(), res.end(), resv.begin());

        // way1: range constructor
        //vector<vector<int> > resv(res.begin(), res.end());

        // way3: std::vector::assign
        vector<vector<int> > resv;
        resv.assign(res.begin(), res.end());

        return resv;

    }
};

Solution 2: Vector using while skip --- k-sum

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int> > res;

        int n = nums.size();
        if (n < 3) return res;

        sort(nums.begin(), nums.end());

        for (int i = 0; i < n - 1; ++i) {
            // important condition!!
            if ( i > 0 && nums[i] == nums[i-1]) continue;
            // bug: [-4, -1, -1, 0, 1, 2], will skip [-1, -1, 2]
            //if (nums[i] == nums[i+1]) continue;

            int j = i + 1;
            int k = n - 1;
            while (j < k) {
                int sum = nums[i] + nums[j] + nums[k];
                if (sum == 0) {
                    res.push_back( {nums[i], nums[j], nums[k]} );
                    ++j;
                    --k;
                    // first --k, then check nums[k] == nums[k+1]
                    // only increase from one side is OK
                    while (nums[j] == nums[j-1] && nums[k] == nums[k+1] && j < k) ++j;
                } else if (sum < 0) {
                    ++j;
                    while (nums[j] == nums[j-1] && j < k) ++j;
                } else {
                    --k;
                    while (nums[k] == nums[k+1] && j < k) --k;
                }
            }
        }

        return res;
    }
};

3Sum Closest

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        int ans;
        int min_gap = INT_MAX;
        int n = nums.size();
        if (n < 3) return 0;

        sort(nums.begin(), nums.end());

        for (int i = 0; i < n -1; ++i) {
            int j = i + 1;
            int k = n -1;
            while (j < k) {
                int sum = nums[i] + nums[j] + nums[k]; 
                int gap = abs(sum- target);

                if ( gap < min_gap) {
                    ans = sum;
                    min_gap = gap;
                }
                // Notice!!!
                if (sum < target) ++j;
                else --k;
            }
        }
        return ans;
    }
};

3Sum Smaller

class Solution {
public:
    int threeSumSmaller(vector<int>& nums, int target) {
        int ans = 0;
        int n = nums.size();
        if (n < 3) return 0;

        sort(nums.begin(), nums.end());

        for (int i = 0; i < n -1; ++i) {
            int j = i + 1;
            int k = n -1;
            while (j < k) {
                int sum = nums[i] + nums[j] + nums[k]; 
                //cout << "i " << i<< " j: " << j <<" k: " << k << " sum: " << sum << endl;

                if (sum < target) {
                    // bug
                    //ans++;
                    ans += k - j;
                    ++j;
                } else 
                    --k;
            }
        }
        return ans;
    }
};

results matching ""

    No results matching ""