Skip to content

Commit 6d393cd

Browse files
committed
Add some solves
1 parent 1caed4a commit 6d393cd

File tree

5 files changed

+216
-0
lines changed

5 files changed

+216
-0
lines changed

373/step1_fix.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
step1 after review
3+
*/
4+
5+
class Solution {
6+
public:
7+
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
8+
int64_t left = nums1.front() + nums2.front();
9+
int64_t right = nums1.back() + nums2.back() + 1;
10+
while (left < right) {
11+
int64_t mid = left + (right - left) / 2;
12+
int count = count_less_pairs(nums1, nums2, mid, k);
13+
if (count >= k) {
14+
right = mid;
15+
} else {
16+
left = mid + 1;
17+
}
18+
}
19+
20+
int max_sum = left;
21+
priority_queue<SumPair> sum_pairs;
22+
for (int num1 : nums1) {
23+
for (int num2 : nums2) {
24+
if (num1 + num2 > max_sum) {
25+
break;
26+
}
27+
sum_pairs.push({num1 + num2, {num1, num2}});
28+
if (sum_pairs.size() > k) {
29+
sum_pairs.pop();
30+
if (num1 + num2 == sum_pairs.top().sum) {
31+
break;
32+
}
33+
}
34+
}
35+
}
36+
37+
vector<vector<int>> answer;
38+
while (!sum_pairs.empty()) {
39+
answer.push_back(sum_pairs.top().pair);
40+
sum_pairs.pop();
41+
}
42+
return answer;
43+
}
44+
private:
45+
46+
struct SumPair {
47+
int sum;
48+
vector<int> pair;
49+
50+
bool operator< (const SumPair& other) const {
51+
return sum < other.sum;
52+
}
53+
};
54+
55+
int count_less_pairs(vector<int> nums1, vector<int>nums2, int num, int limit) {
56+
int num_pairs = 0;
57+
for (int num1 : nums1) {
58+
auto it = upper_bound(nums2.begin(), nums2.end(), num - num1);
59+
num_pairs += distance(nums2.begin(), it);
60+
if (num_pairs > limit) {
61+
return limit;
62+
}
63+
}
64+
return num_pairs;
65+
}
66+
};

373/step2_2.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
step2 after review
3+
*/
4+
class Solution {
5+
public:
6+
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
7+
priority_queue<SumIndex> sum_index;
8+
set<vector<int>> visited;
9+
vector<vector<int>> answer;
10+
sum_index.push({nums1[0] + nums2[0], {0, 0}});
11+
while (answer.size() < k) {
12+
int i = sum_index.top().index[0];
13+
int j = sum_index.top().index[1];
14+
sum_index.pop();
15+
answer.push_back({nums1[i], nums2[j]});
16+
if (i + 1 < nums1.size() && !visited.contains({i + 1, j})) {
17+
sum_index.push({nums1[i + 1] + nums2[j], {i + 1, j}});
18+
visited.insert({i + 1, j});
19+
}
20+
if (j + 1 < nums2.size() && !visited.contains({i, j + 1})) {
21+
sum_index.push({nums1[i] + nums2[j + 1], {i, j + 1}});
22+
visited.insert({i, j + 1});
23+
}
24+
}
25+
26+
return answer;
27+
}
28+
29+
private:
30+
struct SumIndex {
31+
int sum;
32+
vector<int> index;
33+
34+
bool operator< (const SumIndex& other) const {
35+
return sum > other.sum;
36+
}
37+
};
38+
};

373/step3_3_fix.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
{i + 1, j}と{i, j + 1}をpriority_queueにいれる時に、{i + 1, j - 1}と{i - 1, j + 1}がvisitedに含まれているかを確認して効率化するパターン
3+
条件判定部分が無駄に複雑なので関数化したいが、いい感じにできないのでそのままにしている
4+
*/
5+
class Solution {
6+
public:
7+
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
8+
priority_queue<SumIndex, vector<SumIndex>, greater<SumIndex>> sum_index;
9+
vector<vector<int>> minimum_k_pair;
10+
set<vector<int>> visited;
11+
sum_index.push({nums1[0] + nums2[0], 0, 0});
12+
while (minimum_k_pair.size() < k && sum_index.size() > 0) {
13+
int i = sum_index.top().num1_index;
14+
int j = sum_index.top().num2_index;
15+
sum_index.pop();
16+
minimum_k_pair.push_back({nums1[i], nums2[j]});
17+
if (i + 1 < nums1.size() && !visited.contains({i + 1, j}) && (j == 0 || visited.contains({i + 1, j - 1}))) {
18+
sum_index.push({nums1[i + 1] + nums2[j], i + 1, j});
19+
visited.insert({i + 1, j});
20+
}
21+
if (j + 1 < nums2.size() && !visited.contains({i, j + 1}) && (i == 0 || visited.contains({i - 1, j + 1}))) {
22+
sum_index.push({nums1[i] + nums2[j + 1], i, j + 1});
23+
visited.insert({i, j + 1});
24+
}
25+
}
26+
return minimum_k_pair;
27+
}
28+
29+
private:
30+
struct SumIndex {
31+
int sum;
32+
int num1_index;
33+
int num2_index;
34+
35+
bool operator> (const SumIndex& other) const {
36+
return sum > other.sum;
37+
}
38+
};
39+
};

373/step3_3_no_set.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
https://github.com/colorbox/leetcode/pull/25#discussion_r1759948961
3+
https://github.com/ryoooooory/LeetCode/pull/17/files#diff-1288c579d3218c63304f49c9c9a04568c3305bef4a38145045001270d6f6b5c6
4+
を参考としたコード
5+
右・下移動をpriority_queueから取り出すごとに行うが、下移動は一番上にいるときのみに限って行うことで、衝突を避ける。
6+
*/
7+
class Solution {
8+
public:
9+
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
10+
priority_queue<SumIndex> k_pair_candidates;
11+
vector<vector<int>> minimum_k_pair;
12+
k_pair_candidates.push({nums1[0] + nums2[0], 0, 0});
13+
while (minimum_k_pair.size() < k && k_pair_candidates.size() > 0) {
14+
auto [sum, i, j] = k_pair_candidates.top();
15+
k_pair_candidates.pop();
16+
minimum_k_pair.push_back({nums1[i], nums2[j]});
17+
if (j == 0 && i + 1 < nums1.size()) {
18+
k_pair_candidates.push({nums1[i + 1] + nums2[j], i + 1, j});
19+
}
20+
if (j + 1 < nums2.size()) {
21+
k_pair_candidates.push({nums1[i] + nums2[j + 1], i, j + 1});
22+
}
23+
}
24+
return minimum_k_pair;
25+
}
26+
27+
private:
28+
struct SumIndex {
29+
int sum;
30+
int num1_index;
31+
int num2_index;
32+
33+
bool operator< (const SumIndex& other) const {
34+
return sum > other.sum;
35+
}
36+
};
37+
};

373/step3_3_no_set_2.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
https://github.com/colorbox/leetcode/pull/25#discussion_r1766166184
3+
https://github.com/seal-azarashi/leetcode/pull/10/files#diff-1738c7b2b125c2158f2d6502754f18d9c179c559fca2b92d22d1a6bfc16ce429
4+
上記を参考にしたコード
5+
一旦1行目の候補をすべてpriority_queueにpushし、その後取り出した候補を一つずつ降下させることで重複なく候補を取り出す。
6+
*/
7+
class Solution {
8+
public:
9+
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
10+
priority_queue<SumIndex> k_pair_candidates;
11+
vector<vector<int>> minimum_k_pair;
12+
for (int i = 0; i < nums1.size(); i++) {
13+
k_pair_candidates.push({nums1[i] + nums2[0], i, 0});
14+
}
15+
while (minimum_k_pair.size() < k && k_pair_candidates.size() > 0) {
16+
auto [sum, i, j] = k_pair_candidates.top();
17+
k_pair_candidates.pop();
18+
minimum_k_pair.push_back({nums1[i], nums2[j]});
19+
if (j + 1 < nums2.size()) {
20+
k_pair_candidates.push({nums1[i] + nums2[j + 1], i, j + 1});
21+
}
22+
}
23+
return minimum_k_pair;
24+
}
25+
26+
private:
27+
struct SumIndex {
28+
int sum;
29+
int num1_index;
30+
int num2_index;
31+
32+
bool operator< (const SumIndex& other) const {
33+
return sum > other.sum;
34+
}
35+
};
36+
};

0 commit comments

Comments
 (0)