传送门
5850. 找出数组的最大公约数
思路:最大公约数
时间复杂度:, 为元素数量, 为最大值。
按照题目要求,先找出最大值 和最小值 ,然后求解两者最大公约数即可。
可用辗转相除法求解最大公约数,该算法的时间复杂度为 。也可使用库函数 __gcd,代码量更小。
class Solution {
public:
int findGCD(vector<int>& nums) {
int a = nums[0], b = nums[0];
for (auto c : nums) {
a = min(a, c);
b = max(b, c);
}
return __gcd(a,b);
}
};
5851. 找出不同的二进制字符串
思路:构造
时间复杂度:
设有长度为 的字符串 。容易做到 与 不同,取反即可。
这样的 保证了与任意一个 都至少有一个字符不同,满足题目要求。
class Solution {
public:
string findDifferentBinaryString(vector<string>& nums) {
string anw;
for (int i = 0; i < nums.size(); i++) {
anw += (nums[i][i] == '0' ? '1' : '0');
}
return anw;
}
};
5852. 最小化目标值与所选元素的差
思路:动态规划
时间复杂度:,sum 为 。
设有二维数组 , 表示在前 行中选取 个数,其累加和能否为 。为了方便描述,令下标从 1 开始。
初始状态 ,即从前 0 行中选取了 0 个数,其累加和显然为 0,所以 。
当 时,如果存在 满足 为真,则 为真,反之为假。
答案为 。
class Solution {
public:
bool dp[71][4901] = {0};
int minimizeTheDifference(vector<vector<int>>& mat, int target) {
dp[0][0] = true;
for (int i = 1; i <= mat.size(); i++) {
for (int j = 0; j <= i*70; j++) {
if (dp[i-1][j]) {
for (int k = 0; k < mat[i-1].size(); k++) {
if (j+mat[i-1][k] <= 4900) {
dp[i][j+mat[i-1][k]] = true;
}
}
}
}
}
int anw = INT_MAX;
for (int i = 0; i <= 4900; i++) {
if (dp[mat.size()][i]) {
anw = min(anw, abs(i-target));
}
}
return anw;
}
};
5853. 从子集的和还原数组
思路:构造,剪枝
时间复杂度:,max 为取值上限,即 40000。
设答案为长度为 的数组 。
接下来,开始构造 。从 0 开始枚举 ,如果可将 分为等长的两部分 和 ,并满足
这可以理解为,一部分中每个数都加了 ,另一部分都没加 。
如果 存在于 中,则 即为 ,并更新 ,反之 即为 ,并更新 。
重复上述过程,直到构造完成。
class Solution {
public:
int split(const vector<int> &nums, int val, vector<int> &remain, const unordered_set<int> &mark) {
vector<int> L, R;
int pos = 0;
for (int i = 0; i < nums.size(); i++) {
if (R.size() <= pos || R[pos] != nums[i]) {
if (mark.count(nums[i]+val) == 0) {
return INT_MAX;
}
L.push_back(nums[i]);
R.push_back(nums[i]+val);
} else {
pos++;
}
}
if (L.size() == R.size() && L.size() + R.size() == nums.size()) {
/*
cout << "L: ";
for (auto c : L) {
cout << c << " ";
}
cout << endl << "R: ";
for (auto c : R) {
cout << c << " ";
}
cout << endl;
*/
if (std::find(L.begin(), L.end(), -val) != L.end()) {
std::swap(R, remain);
return -val;
}
std::swap(L, remain);
return val;
}
return INT_MAX;
}
vector<int> recoverArray(int n, vector<int>& sums) {
sort(sums.begin(), sums.end());
auto nums = sums;
vector<int> anw;
unordered_set<int> mark;
for_each(nums.begin(), nums.end(), [&mark] (int x) {mark.insert(x);});
while(anw.size() < n) {
for (int i = 0; i <= 40000; i++) {
int tmp = split(nums, i, nums, mark);
if (tmp != INT_MAX) {
mark.clear();
for_each(nums.begin(), nums.end(), [&mark] (int x) {mark.insert(x);});
anw.push_back(tmp);
break;
}
}
}
return anw;
}
};