LeetCode 2024/6 每日一题 合集

2024-6-1 2928. 给小朋友们分糖果 I

分析

枚举所有可能的方案数即可

代码实现

class Solution {
public:
    int distributeCandies(int n, int limit) {
        int ans = 0;
        for (int a = 0; a <= limit; ++a) {
            for (int b = 0; b + a <= n && b <= limit; ++b) {
                for (int c = 0; a + b + c <= n && c <= limit; ++c) {
                    ans += a + b + c == n;
                }
            }
        }
        return ans;
    }
};

戳这里前往原题(╹▽╹)

2024-6-2 575. 分糖果

代码实现

class Solution {
public:
    int distributeCandies(vector<int>& a) {
        return std::min<int>(std::set<int>(a.begin(), a.end()).size(), size(a) / 2);
    }
};

戳这里前往原题(╹▽╹)

2024-6-3 1103. 分糖果 II

分析

发现如果每次暴力发放\(n + 1\)颗糖果时间复杂度为\(O(\sqrt n)\),因此选择直接枚举

代码实现

class Solution {
public:
    vector<int> distributeCandies(int candies, int num_people) {
        std::vector<int> ans(num_people);
        int cur = 1;
        while (candies > 0) {
            ans[(cur - 1 + num_people) % num_people] += std::min(cur, candies);
            candies -= cur++;
        }
        return ans;
    }
};

戳这里前往原题(╹▽╹)

2024-6-4 3067. 在带权树网络中统计可连接服务器对数目

分析

枚举当前根下存在多少对\((a, b)\)即可,跑两边dfs,第一遍求出root到所有点的距离记录根儿子下符合条件的点有多少,最后数目即为\(\frac{\sum当前儿子符合条件数*其余儿子符合条件数}{2}\)

代码实现

class Solution {
public:
    vector<int> countPairsOfConnectableServers(vector<vector<int>>& edges, int signalSpeed) {
        int n = size(edges) + 1;
        std::vector<std::vector<std::pair<int, int>>> g(n);
        for (auto edge : edges) {
            int a = edge[0], b = edge[1], c = edge[2];
            g[a].emplace_back(b, c);
            g[b].emplace_back(a, c);
        }
        std::vector<int> count(n);
        for (int root = 0; root < n; ++root) {
            int cnt = -1;
            std::vector<int> dist(n);
            auto dfs_dis = [&](auto &&self, int u, int fa)->void {
                cnt += dist[u] % signalSpeed == 0;
                for (auto [v, w] : g[u]) if (v != fa) {
                    dist[v] = dist[u] + w;
                    self(self, v, u);
                }
            };
            dfs_dis(dfs_dis, root, -1);
            auto dfs = [&](auto &&self, int u, int fa)->int {
                int num = dist[u] % signalSpeed == 0;
                for (auto [v, w] : g[u]) if (v != fa) {
                    int t = self(self, v, u);
                    if (fa == -1) {
                        count[root] += t * (cnt - t);
                    }
                    num += t;
                }
                return num;
            };
            dfs(dfs, root, -1);
            count[root] /= 2;
        }
        return count;
    }
};

戳这里前往原题(╹▽╹)

2024-6-5 3072. 将元素分配到两个数组中 II

分析

本题的难度在于如何快速查找数组中严格大于val的位置,可以选择使用离散化加树状数组进行维护。

代码实现

template<typename T>
struct Fenwick {
    const int n;
    std::vector<T> tr;
    Fenwick(int n) : n(n), tr(n + 1) {}
    void add(int x, T c) {
        for (int i = x; i <= n; i += i & -i) tr[i] += c;
    }
    void add(int l, int r, T c) {
        add(l, c);
        if (r + 1 <= n) add(r + 1, -c);
    }
    T get(int x) {
        T res = T();
        for (int i = x; i > 0; i -= i & -i) res += tr[i];
        return res;
    }
    T get(int l, int r) {
        return get(r) - get(l - 1);
    }
    int find_first(T sum) {
        int ans = 0; T val = 0;
        for (int i = std::__lg(n); i >= 0; --i) {
            if ((ans | (1 << i)) <= n and val + tr[ans | (1 << i)] < sum) {
                ans |= 1 << i;
                val += tr[ans];
            }
        }
        return ans + 1;
    }
    int find_last(T sum) {
        int ans = 0; T val = 0;
        for (int i = std::__lg(n); i >= 0; --i) {
            if ((ans | (1 << i)) <= n and val + tr[ans | (1 << i)] <= sum) {
                ans |= 1 << i;
                val += tr[ans];
            }
        }
        return ans;
    }
};
using BIT = Fenwick<int>;
class Solution {
public:
    vector<int> resultArray(vector<int>& nums) {
        int n = size(nums);   
        std::vector<int> ord(n);
        std::iota(ord.begin(), ord.end(), 0);
        std::sort(ord.begin(), ord.end(),
            [&](int x, int y) {
                return nums[x] < nums[y];
            });
        for (int i = 0; i < n; ++i) {
            while (i + 1 < n && nums[ord[i]] == nums[ord[i + 1]]) {
                ord[i + 1] = ord[i];
                i += 1;
            }
        }
        std::unordered_map<int, int> mp;
        for (int i = 0; i < n; ++i) {
            if (!mp.count(nums[ord[i]])) {
                mp[nums[ord[i]]] = i + 1;
            }
        }
        auto greaterCount = [&](BIT &bit, int val) {
            return bit.get(mp[val], n) - bit.get(mp[val], mp[val]);
        };
        BIT bit1(n + 2), bit2(n + 2);
        std::vector<int> arr1{nums[0]}, arr2{nums[1]};
        bit1.add(mp[nums[0]], +1), bit2.add(mp[nums[1]], +1);
        for (int i = 2; i < n; ++i) {
            int p1 = greaterCount(bit1, nums[i]);
            int p2 = greaterCount(bit2, nums[i]);
            if (p1 > p2) {
                arr1.emplace_back(nums[i]);
                bit1.add(mp[nums[i]], +1);
            } else if (p1 < p2) {
                arr2.emplace_back(nums[i]);
                bit2.add(mp[nums[i]], +1);
            } else {
                if (size(arr1) <= size(arr2)) {
                    arr1.emplace_back(nums[i]);
                    bit1.add(mp[nums[i]], +1);
                } else {
                    arr2.emplace_back(nums[i]);
                    bit2.add(mp[nums[i]], +1);
                }
            }
            // debug(arr1, arr2);
        }
        std::vector<int> result;
        result.insert(result.end(), arr1.begin(), arr1.end());
        result.insert(result.end(), arr2.begin(), arr2.end());
        return result;
    }
};

戳这里前往原题(╹▽╹)

2024-6-6 2938. 区分黑球与白球

分析

可以发现每个白球都有最终的固定位置,求一下所有白球到最终位置的距离即可

代码实现

class Solution {
public:
    long long minimumSteps(string s) {
        int n = size(s);
        long long ans = 0;
        for (int i = 0, j = 0; i < n; ++i) {
            if (s[i] == '0') {
                ans += i - j;
                j += 1;
            }
        }
        return ans;
    }
};

戳这里前往原题(╹▽╹)

2024-6-7 3038. 相同分数的最大操作数目 I

代码实现

class Solution {
public:
    int maxOperations(vector<int>& nums) {
        int same = nums[0] + nums[1], cnt = 1;
        for (int i = 2; i < size(nums); i += 2) {
            if (nums[i] + nums[i + 1] == same) {
                cnt += 1;
            } else {
                break;
            }
        }
        return cnt;
    }
};

戳这里前往原题(╹▽╹)

2024-6-8 3040. 相同分数的最大操作数目 II

代码实现

class Solution {
public:
    int maxOperations(vector<int>& nums) {
        int n = size(nums);
        std::vector<int> cnt(n * n + 10100);
        cnt[2 * n + n - 1 + 1001] = cnt[1 * n + n - 2 + 1001] = cnt[0 * n + n - 3 + 1001] = 1;
        auto dfs = [&](auto &&self, int val, int l, int r) {
            // debug(val, l, r);
            if (r - l < 1) return ;
            // debug(val, l, r);
            if (nums[r] + nums[r - 1] == val && cnt[l * n + r - 2 + 1001] < cnt[l * n + r + 1001] + 1) {
                cnt[l * n + r - 2 + 1001] = cnt[l * n + r + 1001] + 1;
                self(self, val, l, r - 2);
            } 
            if (nums[r] + nums[l] == val && cnt[(l + 1) * n + r - 1 + 1001] < cnt[l * n + r + 1001] + 1) {
                cnt[(l + 1) * n + r - 1 + 1001] = cnt[l * n + r + 1001] + 1;
                self(self, val, l + 1, r - 1);
            } 
            if (nums[l] + nums[l + 1] == val && cnt[(l + 2) * n + r + 1001] < cnt[l * n + r + 1] + 1001) {
                cnt[(l + 2) * n + r + 1001] = cnt[l * n + r + 1001] + 1;
                self(self, val, l + 2, r);
            }
            
        };
        dfs(dfs, nums[0] + nums[1], 2, n - 1);
        dfs(dfs, nums[0] + nums[n - 1], 1, n - 2);
        dfs(dfs, nums[n - 1] + nums[n - 2], 0, n - 3);
        return std::ranges::max(cnt);
    }
};

戳这里前往原题(╹▽╹)

2024-6-9 312. 戳气球

代码实现

class Solution {
public:
    int maxCoins(vector<int>& nums) {
        int n = size(nums);
        std::vector val(n + 2, 1);
        for (int i = 1; i <= n; ++i) {
            val[i] = nums[i - 1];
        }
        std::vector<std::vector<int>> f(n + 2, std::vector<int>(n + 2));
        for (int len = 3; len <= n + 2; ++len) {
            for (int l = 0; l + len - 1 <= n + 1; ++l) {
                int r = l + len - 1;
                for (int k = l + 1; k < r; ++k) {
                    f[l][r] = std::max(f[l][r], f[l][k] + f[k][r] + val[l] * val[k] * val[r]);
                }
            }
        }
        return f[0][n + 1];
    }
};

戳这里前往原题(╹▽╹)

2024-6-10 881. 救生艇

代码实现

class Solution {
public:
    int numRescueBoats(vector<int>& people, int limit) {
        int n = size(people);
        std::sort(people.begin(), people.end());
        int l = 0, r = n - 1, ans = 0;
        while (l <= r) {
            if (people[l] + people[r] <= limit) {
                l += 1, r -= 1, ans += 1;
            } else {
                r -= 1, ans += 1;
            }
        }
        return ans;
    }
};

戳这里前往原题(╹▽╹)

2024-6-11 419. 甲板上的战舰

代码实现

class Solution {
public:
    int countBattleships(vector<vector<char>>& board) {
        int m = size(board), n = size(board[0]);
        int ans = 0;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (board[i][j] == 'X' && (i == 0 || board[i - 1][j] != 'X') && (j == 0 || board[i][j - 1] != 'X')) {
                    ans += 1;
                }
            }
        }
        return ans;
    }
};

戳这里前往原题(╹▽╹)

2024-6-12 2806. 取整购买后的账户余额

代码实现

class Solution {
public:
    int accountBalanceAfterPurchase(int purchaseAmount) {
        return 100 - (int)((double)purchaseAmount / 10 + 0.5) * 10;
    }
};

戳这里前往原题(╹▽╹)

2024-6-13 2813. 子序列最大优雅度

分析

显然的对于小于k的首次出现的\(profit_i\)必取,对于相同的\(category_i\)可以先加入栈,看后续是否有更优解进行替换。

代码实现

class Solution {
public:
    long long findMaximumElegance(vector<vector<int>>& items, int k) {
        int n = size(items);
        std::sort(items.begin(), items.end(), 
		[&](const std::vector<int> &x, const std::vector<int> &y) {
			return x[0] != y[0] ? x[0] > y[0] : x[1] > y[1];
		});
        std::map<int, int> mp;
        long long ans = 0, sum = 0;
        std::vector<std::pair<int, int>> stk;
        for (int i = 0; i < n; ++i) {
            if (i < k) {
                sum += items[i][0];
                if (mp.count(items[i][1])) {
                    stk.emplace_back(items[i][0], items[i][1]);
                }
                mp[items[i][1]] += 1;
            } else if (!mp.count(items[i][1]) && size(stk) != 0) {
                sum += items[i][0] - stk.rbegin()[0].first;
                stk.pop_back();
                mp[items[i][1]] += 1;
            }
            ans = std::max<long long>(ans, size(mp) * size(mp) + sum);
        }
        return ans;
    }
};

戳这里前往原题(╹▽╹)

2024-6-14 2786. 访问数组中的位置使分数最大

代码实现

class Solution {
public:
    long long maxScore(vector<int>& nums, int x) {
        int n = size(nums);
        std::vector<std::array<long long, 2>> f(n, {(long long)-1e9, (long long)-1e9});
        f[0][nums[0] & 1] = nums[0];
        for (int i = 1; i < n; ++i) {
            int v = nums[i] & 1;
            f[i] = f[i - 1];
            f[i][v] = std::max(f[i][v], f[i][v ^ 1] - x) + nums[i];
        }
        return std::max(f[n - 1][0], f[n - 1][1]);
    }
};

戳这里前往原题(╹▽╹)

2024-6-15 2786. 访问数组中的位置使分数最大

分析

差分,转换成区间最大值

代码实现

class Solution {
public:
    int maximumBeauty(vector<int>& nums, int k) {
        int n = size(nums);   
        const int W = 1e5;
        for (int i = 0; i < n; ++i) {
            nums[i] += W;
        }
        std::vector<int> pre(W * 3 + 2);
        for (int i = 0; i < n; ++i) {
            pre[nums[i] - k] += 1;
            pre[nums[i] + k + 1] -= 1;
        }
        for (int i = 1; i <= 3 * W; ++i) {
            pre[i] += pre[i - 1];
        }
        return std::ranges::max(pre);
    }
};

戳这里前往原题(╹▽╹)

2024-6-16 2786. 访问数组中的位置使分数最大

代码实现

class Solution {
public:
    int findLUSlength(string a, string b) { 
        if (a != b) {
            return std::max(size(a), size(b));
        } else {
            return -1;   
        }
    }
};

戳这里前往原题(╹▽╹)

2024-6-17 522. 最长特殊序列 II

分析

直接贪心枚举即可

代码实现

class Solution {
public:
    int findLUSlength(vector<string>& strs) {
        int n = size(strs);
        std::sort(strs.begin(), strs.end(), 
            [&](const std::string &a, const std::string&b) {
                return size(a) > size(b);
            });
        auto check = [&](const std::string &s, const std::string &t) {
            int idx = 0;
            for (auto c : t) {
                if (s[idx] == c && ++idx == size(s)) {
                    return true;
                }
            }
            return false;
        };
        for (int i = 0; i < n; ++i) {
            bool ok = true;
            for (int j = 0; j < n; ++j) if (i != j && check(strs[i], strs[j])) {
                ok = false;
            }
            if (ok) return size(strs[i]);
        }
        return -1;
    }
};

戳这里前往原题(╹▽╹)

2024-6-18 2288. 价格减免

代码实现

class Solution {
public:
    string discountPrices(string sentence, int discount) {
        std::stringstream cin(sentence), cout;
        cout << std::fixed << std::setprecision(2);
        std::vector<std::string> strs;
        std::string s;
        while (cin >> s) {
            strs.push_back(s);
        }
        // debug(strs);
        for (auto &str : strs) {
            if (str[0] == '$' && size(str) > 1 && std::all_of(str.begin() + 1, str.end(), ::isdigit)) {
                double price = std::stod(str.substr(1)) * (1.0 - (double)discount / 100);
                cout << '$' << price << ' ';
            } else {
                cout << str << ' ';
            }
        }
        std::string ans = cout.str();
        ans.pop_back();
        return ans;
    }
};

戳这里前往原题(╹▽╹)

2024-6-19 2713. 矩阵中严格递增的单元格数

代码实现

class Solution {
public:
    int maxIncreasingCells(vector<vector<int>>& mat) {
        int n = size(mat), m = size(mat[0]);
        std::map<int, std::vector<std::pair<int, int>>> mp;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                mp[mat[i][j]].emplace_back(i, j);
            }
        }
        std::vector<int> col_max(m), row_max(n);
        for (auto [_, pos] : mp) {
            std::vector<int> f;
            for (auto [x, y] : pos) {
                f.push_back(std::max(row_max[x], col_max[y]) + 1);
            }
            for (int i = 0; i < size(pos); i++) {
                auto [x, y] = pos[i];
                row_max[x] = std::max(row_max[x], f[i]); 
                col_max[y] = std::max(col_max[y], f[i]); 
            }
        }
        return std::ranges::max(row_max);
    }
};

戳这里前往原题(╹▽╹)

2024-6-20 2748. 美丽下标对的数目

代码实现

class Solution {
public:
    int countBeautifulPairs(vector<int>& nums) {
        int sum = 0;
        for (int i = 0; i < size(nums); ++i) {
            while (nums[i] >= 10) nums[i] /= 10;
            for (int j = i + 1; j < size(nums); ++j) {
                sum += std::gcd(nums[i], nums[j] % 10) == 1;
            }
        }
        return sum;
    }
};  

戳这里前往原题(╹▽╹)

2024-6-21 LCP 61. 气温变化趋势

代码实现

class Solution {
public:
    int temperatureTrend(vector<int>& A, vector<int>& B) {
        int ans = 0, same = 0;
        auto cmp = [&](int a, int b) {
            return a > b ? -1 : a == b;
        };
        for (int i = 1; i < size(A); ++i) {
            if (cmp(A[i], A[i - 1]) == cmp(B[i], B[i - 1])) {
                same += 1;
                ans = std::max(ans, same);
            } else same = 0;
        }
        return ans;
    }
}; 

戳这里前往原题(╹▽╹)

2024-6-22 2663. 字典序最小的美丽字符串

分析

发现只要不存在\(s_i = s_{i-1}\)\(s_i = s_{i - 2}\),则一定不存在大于等于2回文串,因此只需要贪心的维护即可。

代码实现

class Solution {
public:
    string smallestBeautifulString(string s, int k) {
        int n = size(s);
        int idx = n - 1;
        s[idx] += 1;
        while (idx < n) {
            if (s[idx] - 'a' == k) {
                if (idx == 0) return "";
                s[idx] = 'a', s[--idx] += 1;
            } else if (idx > 0 && s[idx] == s[idx - 1] || idx > 1 && s[idx] == s[idx - 2]) {
                s[idx] += 1;
            } else {
                idx += 1;
            }
        }
        return s;
    }
};

戳这里前往原题(╹▽╹)

2024-6-23 520. 检测大写字母

代码实现

class Solution {
public:
    bool detectCapitalUse(string word) {
        bool ok = true;
        for (int i = 2; i < size(word); ++i) {
            ok &= islower(word[i]) == islower(word[i - 1]);
        }
        if (size(word) != 1 && (!ok || word[0] >= 'a' && word[1] <= 'Z')) {
            return false;
        }
        return true;
    }
};

戳这里前往原题(╹▽╹)

2024-6-24 503. 下一个更大元素 II

代码实现

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        int n = size(nums);
        std::vector<int> ans(n, -1), stk;
        for (int i = 0; i < 2 * n - 1; ++i) {
            while (size(stk) && nums[stk.back()] < nums[i % n]) {
                ans[stk.back()] = nums[i % n];
                stk.pop_back();
            }
            stk.emplace_back(i % n);
        }
        return ans;
    }
};

戳这里前往原题(╹▽╹)

2024-6-25 2732. 找到矩阵中的好子集

分析

发现\(n\)非常小,种类最多为\(2^n\)个,因此直接记录所有种类所在的位置,最后再进行枚举即可。

代码实现

class Solution {
public:
    vector<int> goodSubsetofBinaryMatrix(vector<vector<int>>& grid) {
        std::unordered_map<int, int> mp;
        for (int i = 0; i < size(grid); ++i) {
            int cost = 0;
            for (int j = 0; j < size(grid[i]); ++j){
                cost |= grid[i][j] << j;
            }
            mp[cost] = i;
            if (cost == 0) return {i};
        }
        for (auto [x, a] : mp) {
            for (auto [y, b] : mp) {
                if ((x & y) == 0) {
                    return {std::min(a, b), std::max(a, b)};
                }
            }
        }
        return {};
    }
};

戳这里前往原题(╹▽╹)

2024-6-26 2741. 特别的排列

代码实现

using LL = long long;
class Solution {
public:
    int specialPerm(vector<int>& nums) {
        const int P = 1e9 + 7;
        int n = size(nums);
        std::vector f((1 << n) - 1, std::vector<LL>(n, -1));
        auto dfs = [&](auto &&self, int s, int t)->LL {
            if (s == 0) return 1;
            LL &u = f[s][t];
            if (u != -1) return u;
            u = 0;
            for (int i = 0; i < n; ++i) {
                if ((s >> i & 1) && (nums[i] % nums[t] == 0 || nums[t] % nums[i] == 0)) {
                    u += self(self, s ^ (1 << i), i);
                }
            }
            return u;        
        };
        LL ans = 0;
        for (int i = 0; i < n; ++i) {
            ans += dfs(dfs, (1 << n) - 1 ^ (1 << i), i);
            ans %= P;
        }
        return ans;
    }
};

戳这里前往原题(╹▽╹)

2024-6-27 2734. 执行子串操作后的字典序最小字符串

代码实现

class Solution {
public:
    string smallestString(string s) {
        if (std::count(s.begin(), s.end(), 'a') == size(s)) {
            s.rbegin()[0] = 'z';
            return s;
        }
        int idx = 0;
        while (idx < (int)size(s) && s[idx] == 'a') {
            idx += 1;
        }
        while (idx < (int)size(s) && s[idx] != 'a') {
            s[idx]--;
            idx += 1;
        }
        return s;
    }
};

戳这里前往原题(╹▽╹)

2024-6-28 2742. 给墙壁刷油漆

代码实现

class Solution {
public:
    int paintWalls(vector<int>& cost, vector<int>& time) {
        int n = size(cost);
        std::vector<int> f(n + 1, 1e9);
        f[0] = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = n; j >= 0; --j) {
                f[j] = std::min(f[j], f[std::max(j - time[i] - 1, 0)] + cost[i]);
            }
        }
        return f[n];
    }
};

戳这里前往原题(╹▽╹)

2024-6-29 2710. 移除字符串中的尾随零

代码实现

class Solution {
public:
    string removeTrailingZeros(string num) {
        int p = size(num) - 1;
        while (p >= 1 && num[p] == '0') {
            p--;
        }
        return num.substr(0, p + 1);
    }
};

戳这里前往原题(╹▽╹)

2024-6-30 494. 目标和

代码实现

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        int n = size(nums);
        int ans = 0;
        auto dfs = [&](auto &&self, int u, int cost)->void {
            if (u == n) {
                ans += target == cost;
                return ;
            }
            self(self, u + 1, cost + nums[u]);
            self(self, u + 1, cost - nums[u]);
        };
        dfs(dfs, 0, 0);
        return ans;
    }
};

戳这里前往原题(╹▽╹)

posted @ 2024-06-01 08:55  sleeeeeping  阅读(15)  评论(0编辑  收藏  举报