【LeetCode】15. 3 Sum(C++)


与えられたint型配列から、合計した値が0になる3つの数値のパターンを全て探す問題です。

下記は時間計算量O(N^2 log N)の一例です。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        std::sort(nums.begin(), nums.end());
        std::set<std::vector<int>> return_value;
        for (size_t i = 0; i < nums.size()-2; i++) {
            for (size_t j = i+1; j < nums.size()-1; j++) {
                const int target = -(nums[i] + nums[j]);
                if (target < nums[j+1] || nums.back() < target) {
                    continue;
                }
                auto it = std::lower_bound(nums.cbegin()+j+1, nums.cend(), target);
                if (*it == target) {
                    return_value.insert({ nums[i], nums[j], target });
                }
            }
        }
        return std::vector<std::vector<int>>(return_value.cbegin(), return_value.cend());
    }
};

大まかには下記のことを行っています

  1. 昇順にソート ( O(N log N) )
  2. 末尾の要素を除き、2つの値の全てのペアを探す ( O(N^2) )
  3. 2. のペアに対して、合計が0になる値を2分探索を使用して値を探す ( O(log N) )
  4. 該当する値があれば、ユニークなコンテナ( std::set )に挿入する
  5. ユニークなコンテナを std::vector に変換して返却

従って時間計算量は 2. × 3. の O(N^2 log N) になります。

余談ですが、 std::set は2分木で実装されています。
Hash Set である std::unordered_set は使用できないか調べた結果、テンプレートパラメータ「Hash (= std::hash )」の実装にstd::vectorは存在しないため、自作のHash関数を指定する必要がありそうです。(参考: C++ unordered_set of vectors)

以上です!

,

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です