1 5759. 找出所有子集的异或总和再求和
class Solution {
public:
int subsetXORSum(vector<int>& nums) {
int n = nums.size();
if(!n)return 0;
int res = 0;
for(int i = 0; i < (1 << n); i++)
{
int t = 0;
for(int j = 0; j < n; j++)
if(i >> j & 1)
t ^= nums[j];
res += t;
}
return res;
}
};
2 5760. 构成交替字符串需要的最小交换次数
思路:
- 分类讨论:(交替字符串)
- 长度为奇数:含量较多的数开头。
- 长度为偶数:0开头或1开头,分别运算结果取较小。
- 非法:字符串中1与0的个数之差的绝对值大于1。
- 将字符串与交替字符串(偶数长度串比较两次)进行比较,得到不同的字符个数cnt,因为每次交换0和1,所以将cnt/2即为待选答案。
class Solution {
public:
int minSwaps(string s) {
int n = s.size();
//判断非法,cnt为字符串中1的个数
int cnt = 0;
for(int i = 0; i < n; i++)
cnt += (s[i] == '1');
if(abs(n - cnt - cnt) > 1)
return -1;
//0开头的交替字符串
int cnt1 = 0;
for(int i = 0; i < n; i++)
{
char num = '0' + (i % 2);
cnt1 += (s[i] != num);
}
//1开头的交替字符串
int cnt2 = 0;
for(int i = 0; i < n; i++)
{
char num = '0' + (i % 2 == 0);
cnt2 += (s[i] != num);
}
int res;
if(n % 2 == 0)//偶数长度
res = min(cnt1 / 2, cnt2 / 2);
else//奇数长度
{
if(cnt * 2 > n)res = cnt2 / 2;//1含量更多
else res = cnt1 / 2;//0含量更多
}
return res;
}
};
3 5761. 找出和为指定值的下标对
参考:官方题解
PS:做题的时候脑子抽风了,拼命往双指针方向去搞,排序,哈希映射,双指针,人没了。
思路:nums1比较短,可以将nums2存到map中,count时枚举nums1并查询map。
class FindSumPairs {
public:
unordered_map<int, int>cnt;
vector<int>a;
vector<int>b;
FindSumPairs(vector<int>& nums1, vector<int>& nums2) {
a = nums1;
b = nums2;
for(int i = 0; i < b.size(); i++)
cnt[b[i]]++;
}
void add(int index, int val) {
--cnt[b[index]];
b[index] += val;
++cnt[b[index]];
}
int count(int tot) {
int res = 0;
for(int i = 0; i < a.size(); i++)
res += cnt[tot - a[i]];
return res;
}
};
/**
* Your FindSumPairs object will be instantiated and called as such:
* FindSumPairs* obj = new FindSumPairs(nums1, nums2);
* obj->add(index,val);
* int param_2 = obj->count(tot);
*/
4 5762. 恰有 K 根木棍可以看到的排列数目
参考:官方题解
思路:DP
- f[i, j]表示长度为1到i的木棍进行全排列,从左到右能看到j个木棍的方案,属性为数量。
- 状态转移:(分类)
- 第i个能看到:排列第i个一定是长度为i的木棍,所以状态转移方程为f[i][j] = f[i - 1][j - 1]
- 第i个不能看到:从长度为1到i-1的木棍任选一个放到第i个位置,共有i-1个选择,因为能否看到只看相对长度,所以将剩下的木棍长度重新看成1到i-1,所以状态转移方程为f[i][j] = (i-1) * f[i-1][j]。
- 初始化:f[0][0]=1,f[][]其余均为0。
class Solution {
public:
const int mod = 1e9 + 7;
int rearrangeSticks(int n, int k) {
vector<int>f(k + 1, 0);
f[0] = 1;
for(int i = 1; i <= n; i++)
{
if(i > 1)f[0] = 0;
for(int j = k; j >= 1; j--)
f[j] = f[j - 1] % mod + (i - 1ll) * f[j] % mod;
}
return f[k] % mod;
}
};