• Leetcode - 112双周赛


    一,2839. 判断通过操作能否让字符串相等 I

     该题的题意就是看 单数下标 和 偶数下标的 s1 和 s2 中的字母及其数量是否相等。

    代码如下(也可以使用哈希表来做):

    1. class Solution {
    2. public boolean canBeEqual(String s1, String s2) {
    3. int[] a = new int[26];//统计偶数下标
    4. int[] b = new int[26];//统计奇数下标
    5. for(int i=0; i<s1.length(); i+=2){
    6. a[s1.charAt(i)-'a']++;
    7. a[s2.charAt(i)-'a']--;
    8. if(i+1 < s1.length()){
    9. b[s1.charAt(i+1)-'a']++;
    10. b[s2.charAt(i+1)-'a']--;
    11. }
    12. }
    13. for(int i=0; i<26; i++){
    14. if(a[i]!=0 || b[i]!=0)
    15. return false;
    16. }
    17. return true;
    18. }
    19. }


    二,2840. 判断通过操作能否让字符串相等 II

     这题和上面那题是一个意思,直接复用上面的代码就行,改都不用改,这里就不在写了。


     三,2841. 几乎唯一子数组的最大和

     该题一看就是一道滑动窗口的题目,要找的是长度为 k 的子数组并且子数组中有 >= m 个不同的值,求满足上述条件的子数组中,最大子数组和。

    代码如下:

    1. class Solution {
    2. public long maxSum(List<Integer> nums, int m, int k) {
    3. long ans = 0;
    4. long cur = 0;
    5. Map<Integer,Integer> map = new HashMap<>();
    6. for(int i=0; i<nums.size(); i++){
    7. cur += nums.get(i);
    8. map.put(nums.get(i),map.getOrDefault(nums.get(i),0)+1);
    9. if(i >= k-1){//子数组长度已满
    10. if(map.size() >= m){
    11. ans = Math.max(ans,cur);
    12. }
    13. int out = i - k + 1;//要滑出去的下标
    14. int val = map.get(nums.get(out));
    15. if(val == 1){
    16. map.remove(nums.get(out));
    17. }else{
    18. map.put(nums.get(out),val-1);
    19. }
    20. cur -= nums.get(out);
    21. }
    22. }
    23. return ans;
    24. }
    25. }

    四,2842. 统计一个字符串的 k 子序列美丽值最大的数目

     这道题题目很长,我们先举几个例子来理解一下:

    1.  k = 1,s = "aabbbc"

            ans = 3

    2.  k = 1,s = "aaabbb"

            ans = 3^k*C(2,k) = 6

    3.  k = 2, s = "aaabbb"

            ans = 2*3 = 6 

            //乘法原理

    4.  k = 2, s = "aaabbbccc"

            ans = 3^k*C(3,k)        

            //C(3,k)实际就是从a,b,c中选两个有多少选法,就是数学中的排列组合 

    5.  k = 4, s = "aabbbccdd"

            先选择b,ans = 3,k -= 1

            然后变成 k = 3,s = "aaccdd"

            ans = ans * 2^3 * C(3,3) 

    根据上面举的例子可知,我们需要知道:

            1. 每个字母的出现次数

            2. 出现次数相同的字母个数

            3. 按照出现次数从大到小枚举

    1. class Solution {
    2. private static final long MOD = (long) 1e9 + 7;
    3. /**
    4. TreeMap中存储是有顺序的!!!
    5. TreeMap使用Map.entrySet()是从小到大输出的!!!
    6. HashMap使用Map.entrySet()是随机输出的!!!
    7. */
    8. public int countKSubsequencesWithMaxBeauty(String s, int k) {
    9. int[] cnt = new int[26];
    10. for(int i=0; i<s.length(); i++){
    11. cnt[s.charAt(i)-'a']++;//统计每个字母的出现次数
    12. }
    13. Map<Integer,Integer> map = new TreeMap<>();
    14. for(int x : cnt){
    15. if(x > 0)//TreeMap是从小到大存储数据,我们要从大到小枚举,因此存-x,取-x
    16. map.put(-x,map.getOrDefault(-x,0)+1);
    17. }
    18. //aaabbbcccddd
    19. //<3,4>
    20. //<出现次数,出现次数相同的字母有几个>
    21. long ans = 1;
    22. for(Map.Entry<Integer,Integer> entry : map.entrySet()){
    23. int key = -entry.getKey();//出现次数
    24. int value = entry.getValue();//出现次数相同的字母有几个
    25. if(value >= k)
    26. return (int)(ans*pow(key,k)%MOD*comb(value,k)%MOD);//key^k*C(value,k)
    27. ans = ans*pow(key,value)%MOD;
    28. k -= value;
    29. }
    30. return 0;
    31. }
    32. long pow(long x, int n){//快速幂算法 x^n
    33. long res = 1;
    34. while(n != 0){
    35. if(n%2 != 0){
    36. res = res*x%MOD;
    37. }
    38. x = x*x%MOD;
    39. n/=2;
    40. }
    41. return res;
    42. }
    43. long comb(long n, int k){//数学中的组合排序算法 C(n,k)
    44. long res = n;
    45. for(int i=2; i<=k; i++){
    46. res = res*(--n)/i;
    47. }
    48. return res%MOD;
    49. }
    50. }

  • 相关阅读:
    Qt使用FFmpeg的静态库
    搭载紫光展锐V510平台 移远通信RG500U-EA 5G模组获全球首个GCF认证
    Office登录一直转圈Win10怎么解决?
    产品思维训练 | 亚马逊流量7-8月网站访客流量下降,请分析原因
    构建图像金字塔:探索 OpenCV 的尺度变换技术
    23111707[含文档+PPT+源码等]计算机毕业设计基于javawebmysql的旅游网址前后台-全新项目
    java-php-python-仓库管理系统计算机毕业设计
    Hashmap 1.8知识总结
    Linux-Ubuntu lxml库导入失败 解决方法
    什么是实时操作系统(UCOS简介)
  • 原文地址:https://blog.csdn.net/m0_74859835/article/details/132716313