목차


two pointer 이용해 3개 distinct한 원소의 합으로 target을 구할 수 있는 경우의 수 구하기

#include <vector>
#include <algorithm>

using namespace std;

const int MOD = 1e9 + 7;

long long countPairs(const vector<int>& arr, int& left, int& right, int targetSum);
long long countSameElements(const vector<int>& arr, int& index, int end);
long long countSameElementsReverse(const vector<int>& arr, int& index, int start);

int threeSumMulti(vector<int>& arr, int target) {
    int n = arr.size();
    sort(arr.begin(), arr.end());
    long long ans = 0;

    for (int i = 0; i < n; i++) {
        int targetSum = target - arr[i];
        int left = i + 1;
        int right = n - 1;
        ans = (ans + countPairs(arr, left, right, targetSum)) % MOD;
    }

    return ans;
}

long long countPairs(const vector<int>& arr, int& left, int& right, int targetSum) {
    long long ans = 0;

    while (left < right) {
        int sum = arr[left] + arr[right];

        if (sum < targetSum) {
            left++;
        } else if (sum > targetSum) {
            right--;
        } else {
            if (arr[left] != arr[right]) {
                int countLeft = countSameElements(arr, left, right);
                int countRight = countSameElementsReverse(arr, right, left);
                ans += static_cast<long long>(countLeft) * countRight;
                ans %= MOD;
            } else {
                int count = right - left + 1;
                ans += static_cast<long long>(count) * (count - 1) / 2;
                ans %= MOD;
                break;
            }
        }
    }

    return ans;
}

long long countSameElements(const vector<int>& arr, int& index, int end) {
    int count = 1;
    while (index + 1 < end && arr[index] == arr[index + 1]) {
        count++;
        index++;
    }
    index++;
    return count;
}

long long countSameElementsReverse(const vector<int>& arr, int& index, int start) {
    int count = 1;
    while (index - 1 > start && arr[index] == arr[index - 1]) {
        count++;
        index--;
    }
    index--;
    return count;
}

sliding window와 counting map을 이용해서 Xth smallest integer를 구하기

#include <deque>
#include <map>
#include <vector>
#include <algorithm>

using namespace std;

class Solution {
public:
    vector<int> getSubarrayBeauty(vector<int>& nums, int k, int x) {
        vector<int> transformed_nums = transformNums(nums);
        vector<int> res;

        deque<int> window;
        map<int, int> count_map;

        for (int i = 0; i < transformed_nums.size(); ++i) {
            if (i >= k) {
                removeElementFromWindow(window, count_map);
            }

            addElementToWindow(transformed_nums[i], window, count_map);

            if (i >= k - 1) {
                pushXthElement(count_map, x, res);
            }
        }

        return res;
    }

private:
    vector<int> transformNums(const vector<int>& nums) {
        vector<int> transformed_nums;
        transformed_nums.reserve(nums.size());

        for (auto num : nums) {
            if (num < 0) {
                transformed_nums.push_back(num);
            } else {
                transformed_nums.push_back(0);
            }
        }

        return transformed_nums;
    }

    void addElementToWindow(int element, deque<int>& window, map<int, int>& count_map) {
        window.push_back(element);
        count_map[element]++;
    }

    void removeElementFromWindow(deque<int>& window, map<int, int>& count_map) {
        int to_remove = window.front();
        window.pop_front();
        if (--count_map[to_remove] == 0) {
            count_map.erase(to_remove);
        }
    }

    void pushXthElement(const map<int, int>& count_map, int x, vector<int>& res) {
        int count = 0;
        for (const auto& [num, freq] : count_map) {
            count += freq;
            if (count >= x) {
                res.push_back(num);
                break;
            }
        }
    }
};

Counting map을 이용해 목표 지점의 pointer 존재 여부 확인하기

#include <vector>
#include <unordered_map>
#include <unordered_set>

using namespace std;

class Solution {
public:
    int minAreaRect(vector<vector<int>>& points) {
        int n = points.size();
        unordered_map<int, unordered_set<int>> m;
        for (auto& p : points) {
            m[p[0]].insert(p[1]);
        }
        int res = INT_MAX;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                auto& p1 = points[i];
                auto& p2 = points[j];
                if (isParallel(p1, p2)) continue;
                if (isPointExist(m, {p1[0], p2[1]}) && isPointExist(m, {p2[0], p1[1]})) {
                    res = min(res, rectangleArea(p1, p2));
                }
            }
        }
        return res == INT_MAX ? 0 : res;
    }
};

private:
    bool isParallel(const vector<int>& p1, const vector<int>& p2) {
        return p1[0] == p2[0] || p1[1] == p2[1];
    }

    bool isPointExist(const unordered_map<int, unordered_set<int>>& m, pair<int, int> point) {
        return m[point[0]].count(point[1]) > 0;
    }

    int rectangleArea(const vector<int>& p1, const vector<int>& p2) {
        return abs(p1[0] - p2[0]) * abs(p1[1] - p2[1]);
    }


2024-10-20
다음 글: 10월 5주차 알고리즘 문제 → 카테고리로 돌아가기 ↩