力扣381周赛

力扣第381场周赛

文章目录

  • 力扣第381场周赛
    • [输入单词需要的最少按键次数 I](#输入单词需要的最少按键次数 I)
    • [按距离统计房屋对数目 I](#按距离统计房屋对数目 I)
    • [输入单词需要的最少按键次数 II](#输入单词需要的最少按键次数 II)
    • [按距离统计房屋对数目 II](#按距离统计房屋对数目 II)

输入单词需要的最少按键次数 I

贪心模拟

cpp 复制代码
class Solution {
public:
    int minimumPushes(string word) {
        int n = word.size() , ans = 0;
        for(int i = 0 ; i < n ; i ++){
            if(i >= 0 && i <= 7)ans += 1;
            else if(i >= 8 && i < 16)ans += 2;
            else if(i >= 16 && i < 24)ans += 3;
            else ans += 4;
        }
        return ans;
    }
};

按距离统计房屋对数目 I

跑一边floyd然后对每两个点统计

cpp 复制代码
class Solution {
public:
    vector<int> countOfPairs(int n, int x, int y) {
        vector<vector<int> >d(n + 1 , vector<int>(n + 1));
        vector<int> ans(n);
        for(int i = 1 ; i <= n  ; i ++){
            for(int j = 1 ; j <= n ; j ++){
                if(i == j)d[i][j] = 0;
                else d[i][j] = 1e9;
            }
        }
        
        for(int i = 1 ; i < n ; i ++){
            d[i][i + 1] = d[i + 1][i] = 1;
        }
        if(x != y) d[x][y] = d[y][x] = 1;
           for (int k = 1; k <= n; k ++ )
            for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= n; j ++ )
            d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
        
        for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= n ; j ++){
                if(d[i][j] - 1 >= 0)ans[d[i][j] - 1]++;
            }
        }
        return ans;
    }
};

输入单词需要的最少按键次数 II

在I的基础上价格哈希表即可

cpp 复制代码
class Solution {
public:
    int minimumPushes(string word) {
        map<char,int> m;
        int n = word.size() , ans = 0;
        vector<int> v(30);
        for(auto x: word){
            m[x] ++;
        }
        int i = 1;
        for(auto [x , y] : m){
            v.push_back(y);
        }
        sort(v.begin() , v.end());
        reverse(v.begin() , v.end());
        for(auto y : v){
            if(i >= 1 && i <= 8)ans += y;
            else if(i >= 9 && i <= 16)ans += (2 * y);
            else if(i > 16 && i <= 24)ans += (3 * y);
            else ans += (4 * y);
            i ++;
        }
        return ans;
    }
};

按距离统计房屋对数目 II

分类讨论

cpp 复制代码
class Solution {
public:
    vector<long long> countOfPairs(int n, int X, int Y) {
        if (X > Y) swap(X, Y);

        vector<long long> ans(n + 1);

        // 情况三:计算长度为 len 的链内部的贡献
        auto inner = [&](int len) {
            for (int i = 1; i <= len; i++) ans[i] += (len - i) * 2;
        };

        if (X == Y) {
            // 没有环的特殊情况
            inner(n);
            ans.erase(ans.begin());
            return ans;
        }

        // 情况二:计算元素值为 2,第一个窗口的开头为 L,最后一个窗口的开头为 R 的滑动窗口的贡献
        auto gao = [&](int L, int R, int len) {
            // 用差分数组维护滑动窗口经过的值
            long long delta[n + 2];
            memset(delta, 0, sizeof(delta));
            for (int i = L; i <= R; i++) delta[i] += 4, delta[i + len] -= 4;
            long long now = 0;
            // 求差分数组前缀和,即可得到对每个距离的贡献
            for (int i = L; i < R + len; i++) {
                now += delta[i];
                ans[i] += now;
            }
        };

        int len = Y - X + 1;
        vector<int> chains;//链的长度
        if (n - Y > 0) chains.push_back(n - Y);
        if (X > 1) chains.push_back(X - 1);
        if (len & 1) {
            // 环长为奇数
            // 情况一:计算环内部的贡献
            for (int i = 1; i <= len / 2; i++) ans[i] += len * 2;
            // 情况二:计算一个点在环,一个点在链的贡献
            for (int c : chains) gao(2, c + 1, len / 2);
        } else {
            // 环长为偶数
            // 情况一:计算环内部的贡献
            for (int i = 1; i < len / 2; i++) ans[i] += len * 2;
            ans[len / 2] += len;
            // 情况二:计算一个点在环,一个点在链的贡献
            for (int c : chains) {
                gao(2, c + 1, len / 2 - 1);
                for (int i = 1; i <= c; i++) ans[i + len / 2] += 2;
            }
        }

        // 情况三:计算链内部的贡献
        int sm = 2;
        for (int c : chains) sm += c;
        inner(sm);
        // 扣除重复计算的贡献
        ans[1] -= 2;
        for (int i = Y + 1; i <= n; i++) ans[i - Y + 1] -= 2;
        for (int i = X - 1; i > 0; i--) ans[X - i + 1] -= 2;

        ans.erase(ans.begin());
        return ans;
    }
};

--

相关推荐
资深web全栈开发6 小时前
LeetCode 3623. 统计梯形的数目 I
算法·leetcode·职场和发展·组合数学
Jay20021117 小时前
【机器学习】23-25 决策树 & 树集成
算法·决策树·机器学习
dragoooon347 小时前
[优选算法专题九.链表 ——NO.53~54合并 K 个升序链表、 K 个一组翻转链表]
数据结构·算法·链表
xlq2232213 小时前
22.多态(上)
开发语言·c++·算法
666HZ66613 小时前
C语言——高精度加法
c语言·开发语言·算法
sweet丶13 小时前
iOS MMKV原理整理总结:比UserDefaults快100倍的存储方案是如何炼成的?
算法·架构
D_evil__14 小时前
[C++高频精进] 并发编程:线程基础
c++
云里雾里!14 小时前
力扣 209. 长度最小的子数组:滑动窗口解法完整解析
数据结构·算法·leetcode
Mr_WangAndy15 小时前
C++17 新特性_第二章 C++17 语言特性_std::any和string_view
c++·string_view·c++40周年·c++17新特性·c++新特性any
CoderYanger15 小时前
递归、搜索与回溯-穷举vs暴搜vs深搜vs回溯vs剪枝:12.全排列
java·算法·leetcode·机器学习·深度优先·剪枝·1024程序员节