Skip to content
Open
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
18 changes: 18 additions & 0 deletions include/leetcode/problems/construct-the-minimum-bitwise-array-ii.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "leetcode/core.h"

namespace leetcode {
namespace problem_3315 {

using Func = std::function<vector<int>(vector<int>&)>;

class ConstructTheMinimumBitwiseArrayIiSolution : public SolutionBase<Func> {
public:
//! 3315. Construct the Minimum Bitwise Array II
//! https://leetcode.com/problems/construct-the-minimum-bitwise-array-ii/
vector<int> minBitwiseArray(vector<int>& nums);

ConstructTheMinimumBitwiseArrayIiSolution();
};

} // namespace problem_3315
} // namespace leetcode
94 changes: 94 additions & 0 deletions src/leetcode/problems/construct-the-minimum-bitwise-array-ii.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "leetcode/problems/construct-the-minimum-bitwise-array-ii.h"

namespace leetcode {
namespace problem_3315 {

// 策略1:直接计算后缀连续1的个数,然后减去相应位
// 时间复杂度: O(n log MAX),空间复杂度: O(1)
static vector<int> solution1(vector<int>& nums) {
vector<int> ans;
ans.reserve(nums.size());
for (int num : nums) {
// 计算从最低位开始的连续1的个数
int suffix_ones = 0;
int temp = num;
while ((temp & 1) == 1) {
++suffix_ones;
temp >>= 1;
}
// 如果后缀连续1的个数为0,则无解
if (suffix_ones == 0) {
ans.push_back(-1);
} else {
// 最小x = num - (1 << (suffix_ones - 1))
ans.push_back(num - (1 << (suffix_ones - 1)));
}
}
return ans;
}

// 策略2:使用位运算技巧,直接构造x
// 时间复杂度: O(n log MAX),空间复杂度: O(1)
static vector<int> solution2(vector<int>& nums) {
vector<int> ans;
ans.reserve(nums.size());
for (int num : nums) {
// 找到最低的0位的位置(从0开始),实际上就是后缀连续1的个数
int suffix_ones = 0;
int temp = num;
while ((temp & 1) == 1) {
++suffix_ones;
temp >>= 1;
}
if (suffix_ones == 0) {
ans.push_back(-1);
} else {
// 构造mask,将第(suffix_ones-1)位清零
int mask = 1 << (suffix_ones - 1);
ans.push_back(num & ~mask);
}
}
return ans;
}

// 策略3:使用内置函数__builtin_ctz计算后缀0的个数,从而得到连续1的个数
// 注意:__builtin_ctz(0)是未定义的,但这里temp = num ^ ((1 << suffix_ones) - 1)可能为0
// 更安全的方法:直接计算连续1的个数
// 时间复杂度: O(n),空间复杂度: O(1)
static vector<int> solution3(vector<int>& nums) {
vector<int> ans;
ans.reserve(nums.size());
for (int num : nums) {
// 计算后缀连续1的个数:找到最低的0位
// 方法:计算 (num ^ (num + 1)) >> 1 的尾部0的个数?需要推导
// 更简单:直接循环
int suffix_ones = 0;
int temp = num;
while ((temp & 1) == 1) {
++suffix_ones;
temp >>= 1;
}
if (suffix_ones == 0) {
ans.push_back(-1);
} else {
ans.push_back(num - (1 << (suffix_ones - 1)));
}
}
return ans;
}

ConstructTheMinimumBitwiseArrayIiSolution::ConstructTheMinimumBitwiseArrayIiSolution() {
setMetaInfo({.id = 3315,
.title = "Construct the Minimum Bitwise Array II",
.url = "https://leetcode.com/problems/construct-the-minimum-bitwise-array-ii/"});
registerStrategy("Count Suffix Ones", solution1);
registerStrategy("Bit Mask", solution2);
registerStrategy("Alternative", solution3);
}

vector<int> ConstructTheMinimumBitwiseArrayIiSolution::minBitwiseArray(vector<int>& nums) {
return getSolution()(nums);
}

} // namespace problem_3315
} // namespace leetcode
92 changes: 92 additions & 0 deletions test/leetcode/problems/construct-the-minimum-bitwise-array-ii.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include "leetcode/problems/construct-the-minimum-bitwise-array-ii.h"

#include "gtest/gtest.h"

namespace leetcode {
namespace problem_3315 {

class ConstructTheMinimumBitwiseArrayIiTest : public ::testing::TestWithParam<string> {
protected:
void SetUp() override { solution.setStrategy(GetParam()); }

ConstructTheMinimumBitwiseArrayIiSolution solution;
};

TEST_P(ConstructTheMinimumBitwiseArrayIiTest, Example1) {
vector<int> nums = {2, 3, 5, 7};
vector<int> expected = {-1, 1, 4, 3};
vector<int> result = solution.minBitwiseArray(nums);
EXPECT_EQ(expected, result);
}

TEST_P(ConstructTheMinimumBitwiseArrayIiTest, Example2) {
vector<int> nums = {11, 13, 31};
vector<int> expected = {9, 12, 15};
vector<int> result = solution.minBitwiseArray(nums);
EXPECT_EQ(expected, result);
}

TEST_P(ConstructTheMinimumBitwiseArrayIiTest, AdditionalTest1) {
vector<int> nums = {2};
vector<int> expected = {-1};
vector<int> result = solution.minBitwiseArray(nums);
EXPECT_EQ(expected, result);
}

TEST_P(ConstructTheMinimumBitwiseArrayIiTest, AdditionalTest2) {
vector<int> nums = {3};
vector<int> expected = {1};
vector<int> result = solution.minBitwiseArray(nums);
EXPECT_EQ(expected, result);
}

TEST_P(ConstructTheMinimumBitwiseArrayIiTest, AdditionalTest3) {
vector<int> nums = {5};
vector<int> expected = {4};
vector<int> result = solution.minBitwiseArray(nums);
EXPECT_EQ(expected, result);
}

TEST_P(ConstructTheMinimumBitwiseArrayIiTest, AdditionalTest4) {
vector<int> nums = {7};
vector<int> expected = {3};
vector<int> result = solution.minBitwiseArray(nums);
EXPECT_EQ(expected, result);
}

TEST_P(ConstructTheMinimumBitwiseArrayIiTest, AdditionalTest5) {
vector<int> nums = {131}; // 10000011 binary
// 后缀连续1的个数:最低位1,次低位1,第三位0 -> suffix_ones = 2
// ans = 131 - (1 << 1) = 131 - 2 = 129
// 验证:129 (10000001) OR 130 (10000010) = 131 (10000011)
vector<int> expected = {129};
vector<int> result = solution.minBitwiseArray(nums);
EXPECT_EQ(expected, result);
}

TEST_P(ConstructTheMinimumBitwiseArrayIiTest, AdditionalTest6) {
vector<int> nums = {257}; // 100000001 binary
// 后缀连续1的个数:最低位1,次低位0 -> suffix_ones = 1
// ans = 257 - 1 = 256
// 验证:256 (100000000) OR 257 (100000001) = 257
vector<int> expected = {256};
vector<int> result = solution.minBitwiseArray(nums);
EXPECT_EQ(expected, result);
}

TEST_P(ConstructTheMinimumBitwiseArrayIiTest, AdditionalTest7) {
vector<int> nums = {1023}; // 1111111111 (10 bits)
// 后缀连续1的个数 = 10
// ans = 1023 - (1 << 9) = 1023 - 512 = 511
// 验证:511 (0111111111) OR 512 (1000000000) = 1023 (1111111111)
vector<int> expected = {511};
vector<int> result = solution.minBitwiseArray(nums);
EXPECT_EQ(expected, result);
}

INSTANTIATE_TEST_SUITE_P(
LeetCode, ConstructTheMinimumBitwiseArrayIiTest,
::testing::ValuesIn(ConstructTheMinimumBitwiseArrayIiSolution().getStrategyNames()));

} // namespace problem_3315
} // namespace leetcode