标签:lin amp make 优化 ini air optimize leetcode return
题目链接:5759. 找出所有子集的异或总和再求和
curSum
,加入到答案ans
里class Solution {
private:
int ans;
int n;
public:
void dfs(vector<int>& nums, int u, int curSum) {
if(u == n) {
return ;
}
curSum ^= nums[u];
ans += curSum;
dfs(nums, u + 1, curSum);
curSum ^= nums[u];
dfs(nums, u + 1, curSum);
}
int subsetXORSum(vector<int>& nums) {
n = nums.size();
dfs(nums, 0, 0);
return ans;
}
};
1
和0
的个数cntOne
和cntZero
cntOne
和cntZero
的差的绝对值小于1
1
或以0
开头的情况,计算最小的交换次数1
的个数比0
的个数多1
时,开头的元素只能是1
,反之同理1
和0
的个数一样多,那就分别枚举1
和0
开头的情况,取较小的那个交换次数作为答案class Solution {
private:
int cntOne;
int cntZero;
int n;
int ans;
public:
int minSwaps(string s) {
n = s.size();
for(int i = 0; i < n; ++i) {
if(s[i] == ‘1‘) {
++cntOne;
} else {
++cntZero;
}
}
if(abs(cntOne - cntZero) > 1) { // 无法组成交替字符串
return -1;
}
if(cntOne > cntZero) { // 1 的个数比 0 多,则只能以 1 开头
for(int i = 0; i < n; ++i) {
if(i & 1) {
if(s[i] != ‘0‘) {
++ans;
}
} else {
if(s[i] != ‘1‘) {
++ans;
}
}
}
return ans / 2;
} else if(cntOne < cntZero) { // 0 的个数比 1 多,则只能以 0 开头
for(int i = 0; i < n; ++i) {
if(i & 1) {
if(s[i] != ‘1‘) {
++ans;
}
} else {
if(s[i] != ‘0‘) {
++ans;
}
}
}
return ans / 2;
} else { // 0 和 1 的个数一样多,以 1 或 0 开头都行
int ans0 = 0, ans1 = 0;
for(int i = 0; i < n; ++i) { // 以 0 开头
if(i & 1) {
if(s[i] != ‘1‘) {
++ans0;
}
} else {
if(s[i] != ‘0‘) {
++ans0;
}
}
}
for(int i = 0; i < n; ++i) { // 以 1 开头
if(i & 1) {
if(s[i] != ‘0‘) {
++ans1;
}
} else {
if(s[i] != ‘1‘) {
++ans1;
}
}
}
return min(ans0 / 2, ans1 / 2);
}
return 0;
}
};
题目链接:5761. 找出和为指定值的下标对
nums1
的规模小于1000
,遍历哈希表的操作又比较慢,因此nums1
不用哈希表,直接遍历FindSumPairs
时直接初始化nums2
对应的哈希表即可add
操作也是直接对nums2
的哈希表进行修改count
操作时,遍历nums1
,到nums2
对应的哈希表寻找另一个数的个数,加入到答案ans
中#pragma GCC optimize(3,"Ofast","inline")
class FindSumPairs {
private:
map<int, int> hash2; // nums2 数组对应的哈希表,记录所有元素以及它们在 nums2 中的个数
vector<int> nums1, nums2;
int n, m; // 两个数组的大小
int ans; // count 的答案
public:
FindSumPairs(vector<int>& _nums1, vector<int>& _nums2) {
nums1 = _nums1, nums2 = _nums2;
n = nums1.size();
m = nums2.size();
for(const auto& num : nums2) { // 初始化哈希表
++hash2[num];
}
}
void add(int index, int val) { // nums2 中有元素发生变化,修改哈希表
--hash2[nums2[index]];
if(hash2[nums2[index]] == 0) {
hash2.erase(nums2[index]);
}
nums2[index] += val;
++hash2[nums2[index]];
}
int count(int tot) {
ans = 0;
for(int i = 0; i < n; ++i) { // 遍历 nums1, 到哈希表中寻找另一个数在 nums2 中出现的次数,加入到答案中
if(nums1[i] >= tot) {
continue;
} else {
ans += hash2[tot - nums1[i]];
}
}
return ans;
}
};
/**
* 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);
*/
dp[i][j]
:已经分配了前 i
长的木棍(i
从1
开始)、并且从左侧看可以看到j
根木棍的方案数dp[i + 1][j + 1]
= (dp[i + 1][j + 1]
+ dp[i][j]
) ; 表示把第i + 1长的木棍放在最左侧的方案数j
个,那么由于有i
个可以放木棍的位置,因此我们得到方案数:dp[i + 1][j]
= (dp[i + 1][j]
+ dp[i][j]
; 表示不把第i + 1长的木棍放在最左侧(而是放在比它长的某根木棍的右侧)的方案数dp[n][k]
const int mod = 1e9 + 7;
const int maxn = 1005;
using LL = long long;
LL dp[maxn][maxn];
class Solution {
public:
int rearrangeSticks(int n, int k) {
memset(dp, 0, sizeof dp);
dp[1][1] = 1;
for(int i = 2; i <= n; ++i) {
for(int j = 1; j <= k; ++j) {
dp[i][j] = (dp[i][j] + dp[i - 1][j - 1]) % mod;
dp[i][j] = (dp[i][j] + dp[i - 1][j] * (i - 1)) % mod;
}
}
return dp[n][k];
}
};
标签:lin amp make 优化 ini air optimize leetcode return
原文地址:https://www.cnblogs.com/linrj/p/14774779.html