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;
    }
};
原文地址:https://www.cnblogs.com/Crossea/p/13339538.html