class Solution {
public:
// 此题已经告诉了gcd函数的作用,可以直接拿来用
/*
The std::gcd function in C++ is used to compute the greatest common divisor (GCD) of two integers.
This function is available in the <numeric> header and was introduced in C++17.
C++17 - <algorithm> __gcd
for example:
gcd(12, 9) 返回 12和9的最大公约数3
*/
/*
枚举右,维护左
转换为判断 第j个元素 (最后一个数字) 的美丽下标对个数, cnt数组记录 左侧第一个元素的 数字个数
*/
int countBeautifulPairs(vector<int>& nums){
int ans = 0, cnt[10]{};
for(int num: nums){
// 判断第j个元素的美丽下标对个数
for(int i = 1; i < 10; ++i)
if(cnt[i] && gcd(i, num % 10) == 1) ans += cnt[i];
// 维护第一个数字个数
while(num / 10 > 0)
num /= 10;
++cnt[num % 10];
}
return ans;
}
};
Q:此处若限制使用gcd,又该如何快速求解呢?
可以先预处理出互质表
class Solution {
public:
// 成员变量 - 互质表
const vector<int> coprime[10] = {
{},
{1,2,3,4,5,6,7,8,9},
{1,3,5,7,9},
{1,2,4,5,7,8},
{1,3,5,7,9},
{1,2,3,4,6,7,8,9},
{1,5,7},
{1,2,3,4,5,6,8,9},
{1,3,5,7,9},
{1,2,4,5,7,8}
};
int countBeautifulPairs(vector<int>& nums){
// 记录左侧第一个数字的个数
int hash[10]{};
int ans = 0;
for(int num: nums){
// 取最后一个元素
int x = num % 10;
for(int i = 0; i < coprime[x].size(); ++i)
ans += hash[coprime[x][i]];
// 维护哈希表
while(num / 10 > 0)
num /= 10;
++hash[num];
}
return ans;
}
};
class Solution {
public:
long long maximumTripletValue(vector<int>& nums){
int n = nums.size();
long long ans = 0;
int maxdiff = 0, prefmax = 0;
for(const int& x: nums){
ans = max(ans, 1LL * maxdiff * x); // 1LL妙用:将int类型转换为了long long 类型
maxdiff = max(maxdiff, prefmax - x);
prefmax = max(prefmax, x);
}
return ans;
}
};
for(int right = 1; right < n; ++right){
int x = nums[right];
// 集合 - 可能交换有重复的情况出现(暴力枚举)
unordered_set<int> st = {x};
string s = to_string(x);
int m = s.size();
// 此处怎么生成近似相等数对?
// 交换一个位次(i),然后交换其右侧的任意两个位次
for(int i = 0; i < m; ++i){
for(int j = i + 1; j < m; ++j){
swap(s[i],s[j]);
st.insert(stoi(s));
for(int p = i + 1; p < m; ++p){
for(int q = p + 1; q < m; ++q){
swap(s[p], s[q]);
st.insert(stoi(s));
// 一定要恢复原形
swap(s[p], s[q]);
}
}
swap(s[i], s[j]);
}
}