Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>

Expand All @@ -8,23 +7,22 @@ struct Solution {
static int maxFrequency(std::vector<int> nums, int k, int numOperations) {
std::ranges::sort(nums);
int fMax{0};
int i{nums.front()};
for (size_t a{0}, b{0}; a < nums.size() + 1; ++a) {
if (a < nums.size() && nums[a] == nums[b]) {
// 枚举每个候选数cn
for (int cn{nums.front()}; cn <= nums.back(); ++cn) {
// 二分法计算可通过操作变为cn的数范围[l, r)
auto l{std::ranges::lower_bound(nums, cn - k)};
auto r{std::upper_bound(l, nums.end(), cn + k)};
// 可通过操作变为cn的数,即cn的频率上界
int f{static_cast<int>(r - l)};
if (f <= 0) {
continue;
}
int count = int(a - b);
int limit = (a < nums.size()) ? nums[a] : nums.back() + 1;
while (i < std::min(nums[b] + k + 1, limit)) {
auto l{std::lower_bound(nums.begin(), nums.end(), i - k)};
auto r{std::upper_bound(nums.begin(), nums.end(), i + k)};
int f = std::min<int>(r - l, count + numOperations);
fMax = std::max<int>(fMax, f);
// std::cout << "i: " << i << " " <<r - l << " " << count + numOperations << " " << f << "\n";
++i;
count = 0;
}
b = a;
// 二分法计算重复cn的范围[repl, repr),这些数不需要操作就等于cn
auto repl{std::lower_bound(l, r, cn)};
auto repr{std::upper_bound(repl, r, cn)};
// 考虑操作次数约束
f = std::min(f, static_cast<int>(repr - repl) + numOperations);
fMax = std::max(fMax, f);
}
return fMax;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,10 @@ TEST(LeetCode3346, Regression5) {

TEST(LeetCode3346, Regression6) {
const std::vector<int> nums{111, 21, 21, 13, 11};
Expect<Solution>(1, nums, 3, 0);
Expect<Solution>(2, nums, 3, 0);
}

TEST(LeetCode3346, Regression7) {
const std::vector<int> nums{28, 79, 98, 98, 61, 41};
Expect<Solution>(2, nums, 4, 0);
}
21 changes: 21 additions & 0 deletions leetcode/3347/case.yaml

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions leetcode/3347/solution.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <algorithm>
#include <ranges>
#include <vector>

// 方法1:枚举 + 二分查找 + 数学推导
struct Solution {
static int maxFrequency(std::vector<int> nums, int k, int numOperations) {
std::ranges::sort(nums);
int fMax{0};
// 枚举每个候选数cn
for (std::size_t i{0}; i < nums.size(); ++i) {
if (i > 0 && nums[i - 1] == nums[i]) {
continue;
}
// 只有nums中每个数n及n±k,可能达到最大频率
for (int cn : {nums[i] - k, nums[i], nums[i] + k}) {
if (cn < nums.front() || cn > nums.back()) {
continue;
}
// 二分法计算可通过操作变为cn的数范围[l, r)
auto l{std::ranges::lower_bound(nums, cn - k)};
auto r{std::upper_bound(l, nums.end(), cn + k)};
// 可通过操作变为cn的数,即cn的频率上界
int f{static_cast<int>(r - l)};
if (f <= 0) {
continue;
}
// 二分法计算重复cn的范围[repl, repr),这些数不需要操作就等于cn
auto repl{std::lower_bound(l, r, cn)};
auto repr{std::upper_bound(repl, r, cn)};
// 考虑操作次数约束
f = std::min(f, static_cast<int>(repr - repl) + numOperations);
fMax = std::max(fMax, f);
}
}
return fMax;
}
};