题目描述:
给定三个整数 x 、 y 和 bound ,返回 值小于或等于 bound 的所有 强整数 组成的列表 。
如果某一整数可以表示为 xi + yj ,其中整数 i >= 0 且 j >= 0,那么我们认为该整数是一个 强整数 。
你可以按 任何顺序 返回答案。在你的回答中,每个值 最多 出现一次。
思路:
先分别计算x,y的n次幂;
然后将x,y的n次幂的结果相加,放入到map中,可以去重;
将map的键值push到结果数组中;
其中注意1的情况;
class Solution {
public:
vector<int> powerfulIntegers(int x, int y, int bound) {
unordered_map<int, int> ans;
vector<int> xval;
vector<int> yval;
vector<int> ret;
for (int i = 0; pow(x,i) < bound; ++i) {
xval.push_back(pow(x,i));
if (x == 1) {
break;
}
}
for (int i = 0; pow(y,i) < bound; ++i) {
yval.push_back(pow(y,i));
if (y == 1) {
break;
}
}
for (int i = 0; i < xval.size(); ++i) {
for (int j = 0; j < yval.size(); ++j) {
int val = xval[i] + yval[j];
if (val > bound) {
break;
} else {
ans[val] = 1;
}
}
}
for (auto it = ans.begin(); it != ans.end(); ++it) {
ret.push_back(it->first);
}
return ret;
}
};
题目描述:
给定一副牌,每张牌上都写着一个整数。
此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组:
每组都有 X 张牌。
组内所有的牌上都写着相同的整数。
仅当你可选的 X >= 2 时返回 true。
思路:
先统计每个数字出现的次数,找出最小的出现次数;
因为每组的牌值都一样,且每组的牌数从2开始到mingroup,每次对每个字母出现的次数进行求余,如果有余数存在,则说明当前的牌数分配不合理;
这道题也可以对所有的数字出现的次数求一个公约数,这个公约数如果大于等于2,则说明可以按照题目要求分配,否则返回false;
class Solution {
public:
bool hasGroupsSizeX(vector<int>& deck) {
unordered_map<int, int> ump;
int mingroup = 10010;
sort(deck.begin(),deck.end());
for (int i = 0; i < deck.size(); ++i) {
ump[deck[i]] ++;
}
for (auto it = ump.begin(); it != ump.end(); ++it) {
mingroup = min(mingroup, it->second);
}
for (int i = 2; i <= mingroup; ++ i) {
bool flag = true;
for (auto it = ump.begin(); it != ump.end(); ++it) {
if (it->second % i) {
flag = false;
break;
}
}
if (flag) {
return true;
}
}
return false;
}
};
题目描述:
给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同。
返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。
思路:
前缀和+哈希表
用一个前缀和数组sum[i]表示前i项的和,如果是数字则权重加1,否则减1;
对于任意区间,sum[r]-sum[l-1]代表了[r,l]的和,当这个和为0时,表示数字和字母的个数相等;
于是,可以将等式进行一个转变,变成sum[r] == sum[l-1],这样需要将sum[l-1]插入哈希表,每次遍历的时候去哈希表里头找sum[r],找到一组满足条件的解,计算长度更新最大长度即可;
class Solution {
public:
vector<string> findLongestSubarray(vector<string>& array) {
int sum[100010]; //存前缀和
unordered_map<int,int> hash;
vector<string> ans;
int pre = 0;
for (int i = 0; i < array.size(); ++i) {
sum[i] = pre;
if (array[i][0] >= '0' && array[i][0] <= '9') {
sum[i] ++;
} else {
sum[i] --;
}
pre = sum[i];
}
hash[0] = -1;
int l = 0, r = -1, maxlen = 0; //记录最大长度,最大长度的左边界和右边界
for (int i = 0; i < array.size(); ++i) {
if (hash.find(sum[i]) != hash.end()) {
int len = i - hash[sum[i]];
if (len > maxlen) {
maxlen = len;
l = hash[sum[i]] + 1;
r = i;
}
} else {
hash[sum[i]] = i;
}
}
for (int i = l; i <= r; ++i) {
ans.push_back(array[i]);
}
return ans;
}
};
//重做
题目描述:
给你一个整数数组 arr 和一个整数 k ,其中数组长度是偶数,值为 n 。
现在需要把数组恰好分成 n / 2 对,以使每对数字的和都能够被 k 整除。
如果存在这样的分法,请返回 True ;否则,返回 False 。
思路:
先对所有数进行取余操作;(注意负数的情况)
余数为0的个数为奇数时,则必然不可能分成n/2队,直接返回false;
对比值i和k-i的个数是否相同,不相同则返回false;
否则返回true;
class Solution {
public:
bool canArrange(vector<int>& arr, int k) {
int n = arr.size();
int hash[1000010]; //arr取余k之后的数字
memset(hash, 0, sizeof(hash));
for (int i = 0; i < n; ++i) {
int mod = (arr[i]%k + k) % k;
hash[mod] ++;
}
if (hash[0] & 1) {
return false;
}
for (int i = 1; i < k; ++i) {
if (hash[i] != hash[k-i]) {
return false;
}
}
return true;
}
};