Skip to content
Rain Hu's Workspace
Go back

[LeetCode] 15. 3Sum

Rain Hu

15. 3Sum


一、題目

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets.

Example 1:

Example 2:

Example 3:

Constraints:


二、分析

三、解題

1. HashMap

vector<vector<int>> threeSum(vector<int>& nums) {
    sort(nums.begin(), nums.end());     // 排序
    unordered_map<int,int> map;
    vector<vector<int>> res;
    for (int i = 0; i < nums.size(); i++) {
        map[nums[i]] = i;   // 將值「最右邊」的索引記到 map 中
    }
    for (int i = 0; i < nums.size()-2; i++) {
        for (int j = i+1; j < nums.size()-1; j++) {
            int toFind = -(nums[i] + nums[j]);
            if (toFind < 0) continue;   // 若 nums[i] 與 num[j] 的和為正時,無解。
            if (map.find(toFind) != map.end() && map[toFind] > j) {     // 注意 map 中找到的值的索引,必須比第二個值的索引大
                res.push_back({nums[i], nums[j], toFind});
            }
            j = map[nums[j]];   // 避免重複數組解
        }
        i = map[nums[i]];   // 避免重複數組解
    }
    return res;
}

2. Two Pointer

vector<vector<int>> threeSum(vector<int>& nums) {
    sort(nums.begin(), nums.end());     // 排序
    vector<vector<int>> res;
    for (int i = 0; i < nums.size()-2; i++) {
        if (nums[i] > 0) break;         // 排序後,三數組中最小的值若為正,則無解
        int j = i+1, k = nums.size()-1;
        while (j < k) {
            int sum = nums[i] + nums[j] + nums[k];
            if (sum < 0) {              // 三數組合小於零,左指標右移。
                while (j+1 < k && nums[j] == nums[j+1]) j++;    // 優化,同樣的值不需重複檢查
                j++;
            } else if (sum > 0) {       // 三數組合大於零,右指標左移。
                while (k-1 > j && nums[k-1] == nums[k]) k--;    // 優化,同樣的值不需重複檢查
                k--;
            } else {
                res.push_back({nums[i], nums[j], nums[k]});
                while (j+1 < k && nums[j] == nums[j+1]) j++;    // 避免重複數組解
                while (k-1 > j && nums[k-1] == nums[k]) k--;    // 避免重複數組解
                j++;
                k--;
            }
        }
        while (i+1 < nums.size()-2 && nums[i] == nums[i+1]) i++;    // 避免重複數組解
    }
    return res;
}

參考文章: [LeetCode] 18. 4Sum
回目錄 Catalog


Share this post on:

Previous
[LeetCode] 16. 3Sum Closet
Next
[LeetCode] 30. Substring with Concatenation of All Words