1.数组乘积中的不同质因数数目
给你一个正整数数组 nums
,对 nums
所有元素求积之后,找出并返回乘积中 不同质因数 的数目。
注意:
请你返回正整数数组 ans = [nums1, nums2]
。如果有多个整数对满足上述条件,请你返回 nums1
最小的质数对。如果不存在符合题意的质数对,请你返回 [-1, -1]
。
如果一个整数大于 1
,且只能被 1
和它自己整除,那么它是一个质数。
- 质数 是指大于
1
且仅能被1
及自身整除的数字。 - 如果
val2 / val1
是一个整数,则整数val1
是另一个整数val2
的一个因数。 -
示例 1:
输入:nums = [2,4,3,7,10,6] 输出:4 解释: nums 中所有元素的乘积是:2 * 4 * 3 * 7 * 10 * 6 = 10080 = 25 * 32 * 5 * 7 。 共有 4 个不同的质因数,所以返回 4 。
- 代码:C++
-
class Solution { public: int distinctPrimeFactors(vector<int>& nums) { int i,j=2,x=1; //哈希表 unordered_set<int> se; for(i=0;i<nums.size();i++){ j=2; x=nums[i]; while(x>=j){ while(x%j==0){ x=x/j; se.insert(j); } j++; } } //返回不同整数个数 return se.size(); } };
2.范围内最接近的两个质数
-
给你两个正整数
left
和right
,请你找到两个整数num1
和num2
,它们满足: left <= nums1 < nums2 <= right
。nums1
和nums2
都是 质数 。nums2 - nums1
是满足上述条件的质数对中的 最小值 。
示例 1:
输入:left = 10, right = 19 输出:[11,13] 解释:10 到 19 之间的质数为 11 ,13 ,17 和 19 。 质数对的最小差值是 2 ,[11,13] 和 [17,19] 都可以得到最小差值。 由于 11 比 17 小,我们返回第一个质数对。
代码:C++
class Solution {
public:
vector<int> closestPrimes(int left, int right) {
const int MAXA = 1e6;
// 预处理:求出所有小于等于 1e6 的质数
static bool inited = false;
static bool flag[MAXA + 10];
static vector<int> prime;
if (!inited) {
inited = true;
for (int i = 2; i * i <= MAXA; i++) if (!flag[i]) for (int j = i * 2; j <= MAXA; j += i) flag[j] = true;
for (int i = 2; i <= MAXA; i++) if (!flag[i]) prime.push_back(i);
}
// 记录从 left 到 right 的所有质数
auto it = lower_bound(prime.begin(), prime.end(), left);
vector<int> vec;
for (; it != prime.end(); it++) {
if (*it > right) break;
vec.push_back(*it);
}
// 枚举所有质数,求最优答案
const int INF = 1e7;
int ans1, ans2, best = INF;
for (int i = 1; i < vec.size(); i++) {
int det = vec[i] - vec[i - 1];
if (det < best) ans1 = vec[i - 1], ans2 = vec[i], best = det;
}
if (best < INF) return {ans1, ans2};
else return {-1, -1};
}
};
3. 将字符串分割成值不超过 K 的子字符串
代码(C++):
class Solution {
public:
typedef long long LL;
int minimumPartition(string s, int k) {
// 记录子字符串个数
LL an = 0;
for(int i = 0; i < s.size();)
{
//记录位数 记录数值大小
LL t = 0; LL sum = 0;
//字符数字转换为整形数字
sum = sum * 10 + (s[i] - '0');
//进位
while(sum <= k)
{
t ++;
if(i + t == s.size()) break;
sum = sum * 10 + (s[i + t] - '0');
}
//卡于个位且数值大于限制数则不满足
if(t == 0 && sum > k) return -1;
else i += t, an ++;
}
return an;
}
};
值得一提的是这里有一个小技巧:
将字符数字转换成整型数字
int a = ‘1’ - ‘0’;
进位的话
a = a * 10 + (‘2’ - ‘0’)
结果为12