Leetcode Weekly Contest 198 翻车实录
小学数学
class Solution {
public:
int numWaterBottles(int a, int b) {
int rem = a;
int cnt = a;
while(a/b){
int temp = a/b;
cnt += a/b;
a %= b;
a += temp;
}
return cnt;
}
};
建树加dfs,开数组存结果 O(26n)
class Solution {
public:
vector<int> countSubTrees(int n, vector<vector<int>>& edges, string labels) {
vector<vector<int>> cnt(n+5, vector<int>(26, 0));
vector<vector<int>> g(n, vector<int>());
for(auto e:edges){
g[e[0]].push_back(e[1]);
g[e[1]].push_back(e[0]);
}
dfs(cnt, g, 0, -1, labels);
vector<int> ans(n);
for(int i=0; i<n; i++)
ans[i]=cnt[i][labels[i]-'a'];
return ans;
}
void dfs(vector<vector<int>>& cnt, vector<vector<int>>& g, int id, int fa, string& labels){
cnt[id][labels[id]-'a']++;
for(int i:g[id]){
if(i==fa)
continue;
dfs(cnt, g, i, id, labels);
for(int j=0; j<26; j++)
cnt[id][j] += cnt[i][j];
}
}
};
可以发现这样一个规律,根据&操作的特性,
&的长度越长,结果不会变的更大,所以可以
求前缀和之后二分答案的使用的长度或者双指针
class Solution {
public:
int closestToTarget(vector<int>& arr, int target) {
vector<vector<int>> cnt(arr.size()+1,vector(20, 0));
for(int i=0; i<arr.size(); i++){
for(int j=0; j<20; j++){
cnt[i+1][j] = cnt[i][j];
cnt[i+1][j] += (arr[i]&(1<<j))? 1:0;
}
}
int ans=abs(arr[0]-target);
int l = 0, r = 0;
int cur=0;
while(r<arr.size()){
for(int i=0; i<20; i++)
if(cnt[r+1][i]-cnt[l][i]==r-l+1)
cur |= (1<<i);
while(l<r&&cur<target){
l++;
cur = 0;
for(int i=0; i<20; i++)
if(cnt[r+1][i]-cnt[l][i]==r-l+1)
cur |= (1<<i);
}
ans = min(ans, abs(cur-target));
r++; cur = 0;
}
return ans;
}
};
一条有梦想的咸鱼