【力扣周赛】第 112 场双周赛(统计一个字符串的 k 子序列美丽值最大的数目(贪心+计数+组合数学)

news2024/11/28 18:56:15

文章目录

  • 竞赛链接
  • Q1:7021. 判断通过操作能否让字符串相等 I
  • Q2:7005. 判断通过操作能否让字符串相等 II(贪心)
  • Q3:2841. 几乎唯一子数组的最大和
    • 竞赛时代码——滑动窗口
  • Q4:8050. 统计一个字符串的 k 子序列美丽值最大的数目(贪心+计数+组合数学)
    • 竞赛时代码(赛时通过,结束之后被rejudge了)🤯
    • 正确解法⭐
  • 成绩记录

竞赛链接

https://leetcode.cn/contest/biweekly-contest-112/

Q1:7021. 判断通过操作能否让字符串相等 I

https://leetcode.cn/problems/check-if-strings-can-be-made-equal-with-operations-i/

在这里插入图片描述

提示:
s1.length == s2.length == 4
s1 和 s2 只包含小写英文字母。

class Solution {
    public boolean canBeEqual(String s1, String s2) {
        // 取出各个字符
        char a = s1.charAt(0), b = s1.charAt(1), c = s1.charAt(2), d = s1.charAt(3);
        char a2 = s2.charAt(0), b2 = s2.charAt(1), c2 = s2.charAt(2), d2 = s2.charAt(3);
        // 比较
        return (a == a2 || a == c2) && (a + c == a2 + c2) && (b == b2 || b == d2) && (b + d == b2 + d2);
    }
}

Q2:7005. 判断通过操作能否让字符串相等 II(贪心)

https://leetcode.cn/problems/check-if-strings-can-be-made-equal-with-operations-ii/description/

在这里插入图片描述

提示:
n == s1.length == s2.length
1 <= n <= 10^5
s1 和 s2 只包含小写英文字母。

只要两个字符串的奇偶位的各个字符的数量相等,就一定可以通过交换位置换成相同的字符串。

class Solution {
    public boolean checkStrings(String s1, String s2) {
        // 分别记录两个字符串的奇偶位字符数量
        int[] cnt1 = new int[26], cnt2 = new int[26], cnt3 = new int[26], cnt4 = new int[26];
        int n = s1.length();
        for (int i = 0; i < n; ++i) {
            if (i % 2 == 0) {
                cnt1[s1.charAt(i) - 'a']++;
                cnt3[s2.charAt(i) - 'a']++;
            } else {
                cnt2[s1.charAt(i) - 'a']++;
                cnt4[s2.charAt(i) - 'a']++;
            }
        }
        // 比较是否相等
        return Arrays.equals(cnt1, cnt3) && Arrays.equals(cnt2, cnt4);
    }
}

Q3:2841. 几乎唯一子数组的最大和

https://leetcode.cn/problems/maximum-sum-of-almost-unique-subarray/

在这里插入图片描述
提示:
1 <= nums.length <= 2 * 10^4
1 <= m <= k <= nums.length
1 <= nums[i] <= 10^9

竞赛时代码——滑动窗口

滑动窗口,维护窗口内的总和以及独特元素数量。

class Solution {
    public long maxSum(List<Integer> nums, int m, int k) {
        Map<Integer, Integer> cnt = new HashMap<>();
        int n = nums.size();
        long sum = 0, ans = 0;
        // 双指针+滑动窗口
        for (int i = 0, j = 0; i < n; ++i) {
            // 加入元素
            cnt.merge(nums.get(i), 1, Integer::sum);
            sum += nums.get(i);
            // 移除元素
            if (i - j >= k) {       
                cnt.merge(nums.get(j), -1, Integer::sum);
                sum -= nums.get(j);
                if (cnt.get(nums.get(j)) == 0) cnt.remove(nums.get(j));
                j++;
            }
            // 如果是几乎唯一子数组,就尝试更新答案
            if (i - j + 1 == k && cnt.size() >= m) ans = Math.max(ans, sum);
        }
        return ans;
    }
}

Q4:8050. 统计一个字符串的 k 子序列美丽值最大的数目(贪心+计数+组合数学)

https://leetcode.cn/problems/count-k-subsequences-of-a-string-with-maximum-beauty/
在这里插入图片描述

提示:
1 <= s.length <= 2 * 10^5
1 <= k <= s.length
s 只包含小写英文字母。

竞赛时代码(赛时通过,结束之后被rejudge了)🤯

贪心地选取出现次数最多的字符。

如果若干个字符的出现次数一样,那么就把答案乘上对应的组合数。

比如从 0,1,1,1,2,3 中取 k 为 4,那么 3 和 2 是一定要被选择的,然后在 3 个 1 中任意选择 2 个 1 即可。答案为 3 * 2 * 1 * C(3,2) = 18。

class Solution {
    public int countKSubsequencesWithMaxBeauty(String s, int k) {
        if (k > 26) return 0;

        long[] cnt = new long[26];          // 记录各个字符的数量
        for (char ch: s.toCharArray()) {
            cnt[ch - 'a']++;
        }
        Arrays.sort(cnt);                   // 按字符数量排序
        long ans = 1, MOD = (long)1e9 + 7;
        long mn = cnt[26 - k];              // 可选择的出现次数最少的字符出现次数
        ans = mn;
        // 求组合数是几选几 
        int end = -1;
        for (int i = 26 - k + 1; i < 26; ++i) {
            if (cnt[i] != mn) {
                if (end == -1) end = i;
            }
            ans = (ans * cnt[i]) % MOD;
        }
        if (end == -1) end = 26;
        for (int i = 0; i < end; ++i) {
            if (cnt[i] == mn) {
                int x = end - i;
                long y = op(x, k - 26 + end);   // 求组合数
                ans = (ans * y) % MOD;
                break;
            }
        }
        return (int)ans;
    }
    
    // 求组合数C(x, y)
    public long op(int x, int y) {
        long ans = 1, m = 1;
        while (y != 0) {
            ans *= x;
            m *= y;
            x--;
            y--;
        }
        return ans / m;
    }
}

错误的样例是

"xzkilqoqfdnjextrgqpywahbmsu"
23

预期结果是 132,但是我的代码返回了 0。

原因可能是因为没有考虑到 mn = 0,那后续怎么乘都还是 0。

正确解法⭐

在这里插入图片描述
这种做法的好处是枚举更清晰,代码逻辑也不会混乱。

Q:为什么 k 太大就不存在合法子序列?
A:因为 k 太大时,独特的字母的数量会不够用。

class Solution {
    final long MOD = (long)1e9 + 7;

    public int countKSubsequencesWithMaxBeauty(String s, int k) {
        // 统计每种字符出现的次数
        int[] cnt = new int[26];
        for (char ch: s.toCharArray()) {
            cnt[ch - 'a']++;
        }
        // 统计每种出现次数,以及多少种字符是这种次数
        TreeMap<Integer, Integer> cc = new TreeMap<>();
        for (int c: cnt) {
            if (c > 0) cc.merge(c, 1, Integer::sum);
        }

        long ans = 1;
        // .descendingMap()返回按键降序排序
        for (Map.Entry<Integer, Integer> e: cc.descendingMap().entrySet()) {    
            int c = e.getKey(), num = e.getValue();
            if (num >= k) {
                // 乘上 c^k 和 C(num, k)
                return (int) (ans * pow(c, k) % MOD * comb(num, k) % MOD);
            }
            ans = ans * pow(c, num) % MOD;
            k -= num;
        }
        return 0;       // k太大,没有那么多种字符
    }

    // 计算 x^n 快速幂
    long pow(long x, int n) {
        long res = 1;
        // 把 n 看成二进制数字,哪些位置是 1,就把它乘起来就好了
        for (; n > 0; n /= 2) {
            if (n % 2 == 1) res = res * x % MOD;
            x = x * x % MOD;
        }
        return res;
    }

    // 计算 C(n,k)
    long comb(long n, long k) {
        long res = n;
        for (int i = 2; i <= k; ++i) {
            res = res * --n / i;
        }
        return res % MOD;
    }
}

关于快速幂可见:【算法基础:数学知识】4.4 快速幂

成绩记录

在这里插入图片描述

就,还好。
WA 次数有点多。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/975797.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电子邮件营销实例有哪些?如何做邮件营销?

可参考的电子邮件营销实例&#xff1f;营销邮件制作技巧有什么&#xff1f; 电子邮件营销是当今数字营销领域中的一个关键策略&#xff0c;旨在通过发送定制化的电子邮件与目标受众建立联系&#xff0c;提高品牌知名度、促进销售和培养客户关系。下面将介绍一些电子邮件营销的…

记录一次WMware网络问题

目录 ​编辑 一、问题描述 二、问题排查 2.1 指令ifconfig 查看ip信息 2.2 nmcli n 查看网卡状态 三、问题解决 3.1 启动 NetworkManager 网络管理器 3.2 ifup ens160 启动网卡 一、问题描述 我在我本地电脑上使用WMware虚拟机部署了k8s&#xff0c;有次正常关机后&am…

初试jsvmp加密

分析目标 目标网站 腾讯的点选验证码(我这边是本地环境&#xff0c;所以没有网址) 目标参数 cap_union_new_verify.collect 目标js文件 tdc.js?app_data 流程分析(分析算法) 我们打开我们要分析的网站&#xff0c;过一下点选验证码&#xff0c;抓一包&#xff0c;可以得到…

防雷工程中防雷接地网的应用方案

防雷接地是指在建筑物或其他设施中设置专门的接地装置&#xff0c;以防止雷电对人员、设备和建筑物造成危害的措施。防雷接地工程是防雷工程的重要组成部分&#xff0c;其主要目的是将雷电电流引入大地&#xff0c;消除雷电过电压&#xff0c;降低雷电危险。防雷接地工程应遵循…

BackgroudWork的详细用法,实例

一、什么是BackgroudWorker? 1、简言 backgroudworkd就是一个异步单线程&#xff0c;专门为入门级人员开发的。还可以显示进度条。操作简单实用,属于老技术。 注意&#xff1a;如果调用两次这个线程&#xff0c;将会出错。 2、backgroudwor…

centos7下docker设置新的下载镜像源并调整存放docker下载镜像的仓库位置

目录 1.设置镜像源 2.调整存放下载镜像的仓库位置 1.设置镜像源 在 /etc/docker下创建一个daemon.json文件。在json中下入 "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"] 完成配置 加载配置 systemctl daemon-reload 重启docker sy…

医学影像工作站PACS系统源码,医院PACS系统源码

医学影像(PACS)系统主要进行病人信息和影像的获取、处理、存储、调阅、检索、管理&#xff0c;并通过网络向全院提供病人检查影像及诊断报告&#xff1b;各影像科室之间共享不同设备的病人检查影像及诊断报告&#xff1b;在诊断工作站上&#xff0c;调阅HIS中病人的其它信息&am…

企业架构LNMP学习笔记13

上线商城项目&#xff1a; 1&#xff09;上传项目文件到数据库&#xff1a; 入口文件位置的设计是为了让应用部署更安全&#xff0c;public目录为web可访问目录&#xff0c;其他的文件都可以放到非web访问目录下面。 nginx 默认访问index.html。没有index.html&#xff0c;就会…

软路由ip的优势与劣势:了解其适用场景和限制

在网络技术的快速发展中&#xff0c;软路由IP作为一种灵活且功能强大的网络设备&#xff0c;越来越受到人们的关注。然而&#xff0c;正如任何技术一样&#xff0c;软路由IP也有其优势和劣势。本文将深入探讨软路由IP的优势、劣势以及其适用场景和限制&#xff0c;帮助你更好地…

【回眸】牛客网刷刷刷!(八)——中断专题

目录 前言 1、在CortexM内核中&#xff0c;当系统响应一个中断时 2、用与非门和或非门可以实现其他基本门电路。进而实现任何逻辑电路 3、cpu interface提供了功能包含 4、以Cortex-M3内核为例&#xff0c;如果某个中断在得到响应之前&#xff0c;其请求信号以若干的脉冲的…

kafka-- 安装kafka manager及简单使用

一 、安装kafka manager 管控台&#xff1a; # 安装kafka manager 管控台&#xff1a; ## 上传 cd /usr/local/software ## 解压 unzip kafka-manager-2.0.0.2.zip -d /usr/local/ cd /usr/local/kafka-manager-2.0.0.2/conf vim /usr/local/kafka-manager-2.0.0.2/conf/appl…

MySql学习笔记03——DQL(数据查询)基本命令

DQL 导入数据 首先使用use database进入数据库中&#xff0c;然后使用命令 source D:\mysql_learning\mysql_learning\document\bjpowernode.sql注意文件名不能有双引号&#xff0c;命令结尾没有分号。 SQL脚本 .sql文件是SQL脚本文件&#xff0c;它里面的内容都是SQL语句…

个人炒伦敦银方法大公开

个人炒伦敦银的方法与机构投资者炒这个品种的方法是有不同的&#xff0c;但是双方可能会借鉴一些相同的分析工具&#xff0c;比方说有的机构可能也会使用技术分析&#xff0c;当然&#xff0c;个人投资者对技术分析这个词更是不会陌生。今天我们就从个人投资者的角度出发&#…

计算机竞赛 基于深度学习的人脸识别系统

前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的人脸识别系统 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/…

8、异常机制---- 8.1 Error和Exception

8、异常机制 8.1 Error和Exception 什么是异常 在实际工作中&#xff0c;遇到的情况不可能是非常完美的。比如&#xff1a;你写的某个模块&#xff0c;用户输入不一定符合你的要求、你的程序要打开某个文件&#xff0c;这个文件可能不存在或者文件格式不对&#xff0c;你要读…

23. 带旋转的数独游戏

题目 Description 数独是一个基于逻辑的组合数字放置拼图&#xff0c;在世界各地都很受欢迎。 在这个问题上&#xff0c;让我们关注 网格的拼图&#xff0c;其中包含 个区域。 目标是用十六进制数字填充整个网格&#xff0c;即 &#xff0c;以便每列&#xff0c;每行和每个区…

ABB机器人20032转数计数器未更新故障报警处理方法

ABB机器人20032转数计数器未更新故障报警处理方法 ABB的机器人上面安装有电池,需要定期进行更换(正常一年换一次),如果长时间不更换,电量过低,就会出现转数计数器未更新的报警,各轴编码器的位置就会丢失,在更换新电池后,需要更新转数计数器。 具体步骤如下: 先用手动…

泛微OA流程表单中代码块获取URL的参数

获取URL的参数 需要编辑自定义函数 function getUrlParam(key){var url decodeURI(window.location.href);var paramMap {};var paramStr url.split("?")[2];if (paramStr && paramStr ! "") {var paramStrArr paramStr.split("&&qu…

客户忠诚度和保留率:不良方法的陷阱

良好的客户忠诚度和保留策略是任何电子商务业务成功的关键因素。但当出现问题时会发生什么&#xff1f;您可以采取哪些措施来鼓励忠诚度并减少客户流失&#xff1f;继续阅读以了解不良客户忠诚度和保留实践的后果。 忠诚度和保留率低下的后果 客户不满意和高流失率 客户忠诚…

直播软件app开发中的AI应用及前景展望

在当今数字化时代&#xff0c;直播市场蓬勃发展&#xff0c;而直播软件App成为人们获取实时信息和娱乐的重要渠道。随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;直播软件App开发正逐渐融入AI的应用&#xff0c;为用户带来更智能、更个性化的直播体验。 …