【力扣周赛】第 373 场周赛(交换得到字典序最小的数组 ⭐分解质因子+前缀和+哈希表)

文章目录

  • 竞赛链接
  • Q1:2946. 循环移位后的矩阵相似检查
    • 竞赛时代码——模拟
  • 2947. 统计美丽子字符串 I
    • 竞赛时代码——前缀和+暴力枚举
  • Q3:2948. 交换得到字典序最小的数组
    • 竞赛时代码——排序后判断
    • 相似题目——1202. 交换字符串中的元素(使用并查集 哈希表 复原)🐂
  • Q4:2949. 统计美丽子字符串 II⭐⭐⭐⭐⭐🚹🐂
    • 解法——分解质因子+前缀和+哈希表
    • 相似题目列表(前缀和 + 哈希表)
      • 560. 和为 K 的子数组
      • 974. 和可被 K 整除的子数组
      • 1590. 使数组和能被 P 整除
      • 523. 连续的子数组和
      • 525. 连续数组
      • 面试题 17.05. 字母与数字
      • 1915. 最美子字符串的数目
      • 930. 和相同的二元子数组
      • 1371. 每个元音包含偶数次的最长子字符串
      • 1542. 找出最长的超赞子字符串
  • 成绩记录

竞赛链接

https://leetcode.cn/contest/weekly-contest-373/

Q1:2946. 循环移位后的矩阵相似检查

https://leetcode.cn/problems/matrix-similarity-after-cyclic-shifts/description/

在这里插入图片描述

提示:

1 <= mat.length <= 25
1 <= mat[i].length <= 25
1 <= mat[i][j] <= 25
1 <= k <= 50

竞赛时代码——模拟

class Solution {
    public boolean areSimilar(int[][] mat, int k) {
        int m = mat.length, n = mat[0].length;
        for (int i = 0; i < m; ++i) {
            if (i % 2 == 1) {
                for (int j = 0; j < n; ++j) {
                    if (mat[i][j] != mat[i][(j + k) % n]) return false;
                }
            } else {
                for (int j = 0; j < n; ++j) {
                    if (mat[i][j] != mat[i][(j - k + 50 * n) % n]) return false;
                }
            }
        }
        return true;
    }
}

2947. 统计美丽子字符串 I

https://leetcode.cn/problems/count-beautiful-substrings-i/description/
在这里插入图片描述

提示:

1 <= s.length <= 1000
1 <= k <= 1000
s 仅由小写英文字母组成。

竞赛时代码——前缀和+暴力枚举

class Solution {
    public int beautifulSubstrings(String s, int k) {
        int n = s.length();
        Set<Character> set = Set.of('a', 'e', 'i', 'o', 'u');
        int[] v = new int[n + 1], c = new int[n + 1];
        for (int i = 0; i < n; ++i) {
            v[i + 1] = v[i];
            c[i + 1] = c[i];
            if (set.contains(s.charAt(i))) v[i + 1]++;
            else c[i + 1]++;
        }
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j <= i; ++j) {
                int vc = v[i + 1] - v[j], cc = c[i + 1] - c[j];
                if (vc == cc && (vc * cc % k == 0)) ++ans;
            }
        }
        return ans;
    }
}0

Q3:2948. 交换得到字典序最小的数组

https://leetcode.cn/problems/make-lexicographically-smallest-array-by-swapping-elements/description/
在这里插入图片描述

提示:

1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9
1 <= limit <= 10^9

竞赛时代码——排序后判断

排序之后,可能可以交换的都在一起了,更方便判断。
如果a和b可以交换,b和c可以交换,那么a,b,c的顺序是任意的。

class Solution {
    public int[] lexicographicallySmallestArray(int[] nums, int limit) {
        int n = nums.length;
        // 排序
        Integer[] idx = new Integer[n];
        Arrays.setAll(idx, e -> e);
        Arrays.sort(idx, (x, y) -> nums[x] - nums[y]);
        int[] ans = new int[n];
        for (int i = 0; i < n; ++i) {
            // 记录可以相互交换位置的一组
            List<Integer> ls = new ArrayList<>();
            ls.add(idx[i]);
            int j = i + 1;
            for (; j < n; ++j) {
                if (nums[idx[j]] <= nums[idx[j - 1]] + limit) {
                    ls.add(idx[j]);
                } else break;
            }
            // 交换这一组所有数字的位置,从小到大排列
            List<Integer> ls2 = new ArrayList<>(ls);
            Collections.sort(ls2);
            for (int k = 0; k < ls.size(); ++k) {
                ans[ls2.get(k)] = nums[ls.get(k)];
            }
            i = j - 1;
        }
        return ans;
    }
}

相似题目——1202. 交换字符串中的元素(使用并查集 哈希表 复原)🐂

在这里插入图片描述
提示:

1 <= s.length <= 10^5
0 <= pairs.length <= 10^5
0 <= pairs[i][0], pairs[i][1] < s.length
s 中只含有小写英文字母

class Solution {
    int[] p;

    public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
        int n = s.length();
        p = new int[n];
        Arrays.setAll(p, e -> e);
		// 1.输入并查集
        for (List<Integer> pair: pairs) {
            p[find(pair.get(0))] = find(pair.get(1));
        }
		// 2.利用并查集构建哈希映射
        Map<Integer, PriorityQueue<Character>> m = new HashMap<>();
        for (int i = 0; i < n; ++i) {
            int r = find(i);
            m.computeIfAbsent(r, key -> new PriorityQueue<Character>()).offer(s.charAt(i));
        }
		// 3.利用并查集和哈希映射复原结果字符串
        StringBuilder ans = new StringBuilder();
        for (int i = 0; i < n; ++i) {
            int r = find(i);
            ans.append(m.get(r).poll());
        }
        return ans.toString();
    }

    public int find(int x) {
        if (x != p[x]) p[x] = find(p[x]);
        return p[x];
    }
}

Q4:2949. 统计美丽子字符串 II⭐⭐⭐⭐⭐🚹🐂

https://leetcode.cn/problems/count-beautiful-substrings-ii/description/
在这里插入图片描述

提示:

1 <= s.length <= 5 * 10^4
1 <= k <= 1000
s 仅由小写英文字母组成。

解法——分解质因子+前缀和+哈希表

https://leetcode.cn/problems/count-beautiful-substrings-ii/solutions/2542274/fen-jie-zhi-yin-zi-qian-zhui-he-ha-xi-bi-ceil/

class Solution {
    private static final int AEIOU_MASK = 1065233;

    public long beautifulSubstrings(String s, int k) {
        k = pSqrt(k * 4);
        Map<Integer, Integer> cnt = new HashMap<>();
        int n = s.length();
        int sum = n; // 保证非负
        cnt.put((k - 1) << 17 | sum, 1); // 添加 (k-1, sum)
        long ans = 0;
        for (int i = 0; i < n; i++) {
            int bit = (AEIOU_MASK >> (s.charAt(i) - 'a')) & 1;
            sum += bit * 2 - 1; // 1 -> 1    0 -> -1
            ans += cnt.merge((i % k) << 17 | sum, 1, Integer::sum) - 1; // ans += cnt[(i%k,sum)]++
        }
        return ans;
    }

    private int pSqrt(int n) {
        int res = 1;
        for (int i = 2; i * i <= n; i++) {
            int i2 = i * i;			// 因为次数向上取整
            while (n % i2 == 0) {
                res *= i;
                n /= i2;
            }
            if (n % i == 0) {
                res *= i;
                n /= i;
            }
        }
        if (n > 1) {
            res *= n;
        }
        return res;
    }
}

(i % k) << 17 | sum 是为了把一个 pair 压缩成一个整数。

sum 刚开始设置成 n,其实是 0,为了防止成为负数整体偏移了数组的长度。

相似题目列表(前缀和 + 哈希表)

560. 和为 K 的子数组

https://leetcode.cn/problems/subarray-sum-equals-k/description/
在这里插入图片描述
记得在最开始放入一个和为0的前缀和。

class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> m = new HashMap<>();
        m.put(0, 1);
        int s = 0, ans = 0;
        for (int num: nums) {
            s += num;
            ans += m.getOrDefault(s - k, 0);
            m.merge(s, 1, Integer::sum);
        }
        return ans;
    }
}

974. 和可被 K 整除的子数组

https://leetcode.cn/problems/subarray-sums-divisible-by-k/description/

在这里插入图片描述

提示:

1 <= nums.length <= 3 * 10^4
-104 <= nums[i] <= 10^4
2 <= k <= 10^4

为了元素之和可被 k 整除,将哈希表的键设置为 s % k,注意不能为负。

class Solution {
    public int subarraysDivByK(int[] nums, int k) {
        Map<Integer, Integer> m = new HashMap<>();
        m.put(0, 1);
        int s = 0, ans = 0;
        for (int num: nums) {
            s = ((s + num) % k + k) % k;
            ans += m.getOrDefault(s, 0);
            m.merge(s, 1, Integer::sum);
        }
        return ans;
    }
}

1590. 使数组和能被 P 整除

https://leetcode.cn/problems/make-sum-divisible-by-p/description/

在这里插入图片描述
提示:

1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9
1 <= p <= 10^9

要使得剩余数字之和能被 p 整除,就需要所有数字之和-删去的数字之和能被p整除,即两者%p的结果相等。

为了求最短的子数组,每次存的 key 是最近的下标。

class Solution {
    public int minSubarray(int[] nums, int p) {
        int t = 0, s = 0, n = nums.length;
        for (int x: nums) {
            t = (t + x) % p;
        }
        if (t == 0) return 0;
        Map<Integer, Integer> m = new HashMap<>();
        m.put(0, -1);
        int ans = n;
        for (int i = 0; i < n; ++i) {
            s = (s + nums[i]) % p;
            int tt = ((s - t) % p + p) % p;
            if (m.containsKey(tt)) ans = Math.min(ans, i - m.get(tt));
            m.put(s, i);
        }
        if (ans >= n) return -1;
        return ans;
    }
}

523. 连续的子数组和

https://leetcode.cn/problems/continuous-subarray-sum/description/

在这里插入图片描述

提示:

1 <= nums.length <= 10^5
0 <= nums[i] <= 10^9
0 <= sum(nums[i]) <= 2^31 - 1
1 <= k <= 2^31 - 1

存下 s % k 的第一个出现的下标即可,每次检查相同 s % k 的上一个出现位置是否满足子数组大小至少为 2 的条件。

class Solution {
    public boolean checkSubarraySum(int[] nums, int k) {
        int n = nums.length;
        Map<Integer, Integer> m = new HashMap<>();
        m.put(0, -1);
        int s = 0;
        for (int i = 0; i < n; ++i) {
            s = (s + nums[i]) % k;
            if (m.containsKey(s)) {
                if (i > m.get(s) + 1) return true;
            } else m.put(s, i);
        }
        return false;
    }
}

525. 连续数组

https://leetcode.cn/problems/contiguous-array/description/

在这里插入图片描述

记录的 value 是 1 和 0 的差的前缀和。

class Solution {
    public int findMaxLength(int[] nums) {
        int n = nums.length;
        Map<Integer, Integer> m = new HashMap<>();
        m.put(0, -1);
        int d = 0, ans = 0;
        for (int i = 0; i < n; ++i) {
            d += nums[i] * 2 - 1;
            if (m.containsKey(d)) ans = Math.max(ans, i - m.get(d));
            else m.put(d, i);
        }
        return ans;
    }
}

面试题 17.05. 字母与数字

https://leetcode.cn/problems/find-longest-subarray-lcci/description/

在这里插入图片描述

跟上面的题类似,记录的 value 是字母和数字数量的差。

class Solution {
    public String[] findLongestSubarray(String[] array) {
        int st = 0, ml = 0;     // 记录起始点和最大长度
        int n = array.length, d = 0;
        Map<Integer, Integer> m = new HashMap<>();
        m.put(0, 0);
        for (int i = 0; i < n; ++i) {
            char ch = array[i].charAt(0);
            if (ch >= '0' && ch <= '9') d++;
            else d--;
            if (m.containsKey(d)) {
                int j = m.get(d);
                if (i - j + 1 > ml) {
                    st = j;
                    ml = i - j + 1;
                }
            } else m.put(d, i + 1);
        }
        String[] ans = new String[ml];
        System.arraycopy(array, st, ans, 0, ml);
        return ans;
    }
}

1915. 最美子字符串的数目

https://leetcode.cn/problems/number-of-wonderful-substrings/description/

在这里插入图片描述
提示:

1 <= word.length <= 10^5
word 由从 'a' 到 'j' 的小写英文字母组成

奇偶性可以用异或来表示。
结果可以是:1.没有出现奇数次的;2.枚举每种出现奇数次的字母。
(注意:题目中给出字符的范围是 ‘a’ ~ ‘j’)。

用数组会比用哈希表快很多。

class Solution {
    public long wonderfulSubstrings(String word) {
        long ans = 0;
        int[] cnt = new int[1024];
        cnt[0] = 1;
        int s = 0;
        for (char ch: word.toCharArray()) {
            s ^= 1 << (ch - 'a');
            ans += cnt[s];        // 可以一个都没有
            for (int i = 0; i <= 'j' - 'a'; ++i) {      // 枚举出现奇数次的字符
                ans += cnt[s ^ (1 << i)];
            }
            ++cnt[s];
        }
        return ans;
    }
}

930. 和相同的二元子数组

https://leetcode.cn/problems/binary-subarrays-with-sum/description/

在这里插入图片描述

提示:

1 <= nums.length <= 3 * 10^4
nums[i] 不是 0 就是 1
0 <= goal <= nums.length

class Solution {
    public int numSubarraysWithSum(int[] nums, int goal) {
        int n = nums.length;
        int[] cnt = new int[n + 1];
        cnt[0] = 1;
        int s = 0, ans = 0;
        for (int i = 0; i < n; ++i) {
            s += nums[i];
            if (s >= goal) ans += cnt[s - goal];
            cnt[s]++;
        }
        return ans;
    }
}

1371. 每个元音包含偶数次的最长子字符串

https://leetcode.cn/problems/find-the-longest-substring-containing-vowels-in-even-counts/

在这里插入图片描述

提示:

1 <= s.length <= 5 x 10^5
s 只包含小写英文字母。

状态压缩。
奇偶性用异或来表示,记录每种状态第一次出现的位置。

class Solution {
    public int findTheLongestSubstring(String s) {
        Map<Integer, Integer> cnt = new HashMap<>();
        cnt.put(0, -1);
        int t = 0, ans = 0, mask = 1065233;
        for (int i = 0; i < s.length(); ++i) {
            char ch = s.charAt(i);
            if ((mask & (1 << (ch - 'a'))) != 0) t ^= 1 << (ch - 'a');
            if (cnt.containsKey(t)) ans = Math.max(ans, i - cnt.get(t));
            else cnt.put(t, i);
        }
        return ans;
    }
}

1542. 找出最长的超赞子字符串

https://leetcode.cn/problems/find-longest-awesome-substring/description/

在这里插入图片描述
提示:

1 <= s.length <= 10^5
s 仅由数字组成

等价转换。

class Solution {
    public int longestAwesome(String s) {
        // 等价于至多有一种字符出现奇数次
        int[] pos = new int[1 << 10];
        Arrays.fill(pos, Integer.MAX_VALUE);
        pos[0] = -1;
        int t = 0, ans = 0;
        for (int i = 0; i < s.length(); ++i) {
            t ^= 1 << (s.charAt(i) - '0');
            if (pos[t] != Integer.MAX_VALUE) ans = Math.max(ans, i - pos[t]);
            else pos[t] = i;
            for (int j = 0; j <= 9; ++j) {
                int x = t ^ (1 << j);
                if (pos[x] != Integer.MAX_VALUE) ans = Math.max(ans, i - pos[x]);
            }
        }
        return ans;
    }
}

成绩记录

在这里插入图片描述
T3 脑子抽了其实很简单。
T4 想不到。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)

目录 一、C/C内存分布二、new和delete的使用方式2.1 C语言内存管理2.2 C内存管理2.2.1 new和delete操作内置类型2.2.2 new和delete操作自定义类型 三、new和delete的底层原理3.1 operator new与operator delete函数3.2 原理总结3.2.1 内置类型3.2.2 自定义类型 四、定位new表达…

MFC读取文件数据,添加信息到列表并保存到文件

打开并读取文件信息 添加&#xff1a; BOOL infoDlg::OnInitDialog() {CDialogEx::OnInitDialog();// TODO: 在此添加额外的初始化AfxMessageBox("欢迎查看学生信息");SetList();return TRUE; // return TRUE unless you set the focus to a control// 异常: OCX 属…

Spark编程语言选择:Scala、Java和Python

在大数据处理和分析领域&#xff0c;Apache Spark已经成为一种非常流行的工具。它提供了丰富的API和强大的性能&#xff0c;同时支持多种编程语言&#xff0c;包括Scala、Java和Python。选择合适的编程语言可以直接影响Spark应用程序的性能、可维护性和开发效率。在本文中&…

Json和Xml

一、前言 学习心得&#xff1a;C# 入门经典第8版书中的第21章《Json和Xml》 二、Xml的介绍 Xml的含义&#xff1a; 可标记性语言&#xff0c;它将数据以一种特别简单文本格式储存。让所有人和几乎所有的计算机都能理解。 XML文件示例&#xff1a; <?xml version"1.…

自动驾驶学习笔记(二十二)——自动泊车算法

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo开放平台9.0专项技术公开课》免费报名—>传送门 文章目录 前言 感知算法 定位算法 规划算法…

分享70个Java源码总有一个是你想要的

分享70个Java源码总有一个是你想要的 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1s8ZVYHb5B1GgXMlpG-6-Iw?pwd6666 提取码&#xff1a;6666 项目名称 admin、cms、console 等多…

nodejs+vue+微信小程序+python+PHP的4s店客户管理系统-计算机毕业设计推荐

系统的功能结构是系统实现的框架&#xff0c;本系统的主要结构为管理员和用户、员工。管理员的功能为车辆信息管理、用户管理、售后服务管理、售后安排管理、完成售后管理等。 本系统实现了售后的在线申请与处理&#xff0c;方便了用户和管理员、员工三方的利益&#xff0c;提高…

Linux 宝塔mysql莫名其妙数据库不见了恢复数据库

起因&#xff1a;宝塔安装的mysql 线上运行突然表包括库都不见了&#xff0c;想办法恢复数据库 登陆mysql cd /www/server/mysql/binmysql -u root -p查看binlog日志是否打开 show variables like log_%;log_bin如果为 ON 则为开启状态&#xff0c;如果开启了才可以进行下一…

【SD】差异值 生成 同一人物 制作 表情包 【1】

说明&#xff1a;只对AI生成的人物&#xff0c;效果稳定。 Reference差异值 生成表情 首先生成一张图片。 测试命令&#xff1a;1 man,chibi,full body, 模型&#xff1a;envyclarityxl02_v10.safetensors [f6c13197db] 种子&#xff1a;2704867166 》》测试命令&#xff1a…

智能优化算法应用:基于金豺算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于金豺算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于金豺算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.金豺算法4.实验参数设定5.算法结果6.参考文献7.MA…

力扣:51. N 皇后

题目&#xff1a; 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的…

网络7层架构

网络 7 层架构 什么是OSI七层模型&#xff1f; OSI模型用于定义并理解数据从一台计算机转移到另一台计算机&#xff0c;在最基本的形式中&#xff0c;两台计算机通过网线和连接器相互连接&#xff0c;在网卡的帮助下共享数据&#xff0c;形成一个网络&#xff0c;但是一台计算…

Unity重写Inspector简化分组配置文件

Unity重写Inspector简化分组配置文件 重写Inspector创建分组管理配置文件创建修改参数参数对应类工程在我的资源中名为CreateConfig&#xff0c;免费下载 重写Inspector创建分组管理配置文件 创建 修改参数 参数对应类 using UnityEngine;public class GameConfig : Scriptab…

【UML】第13篇 序列图(2/2)——建模的方法

目录 三、序列图建模 3.1 概述 3.2 建模的步骤 3.3 举例说明步骤 1.确定主要场景和流程 2.确定参与的对象 3.绘制序列图 4.注意事项 3.4 特殊的情况 序列图是我个人认为&#xff0c;UML中最重要的图之一。 而且序列图&#xff0c;对于业务建模&#xff0c;也有非常好…

【Filament】立方体贴图(6张图)

1 前言 本文通过一个立方体贴图的例子&#xff0c;讲解三维纹理贴图&#xff08;子网格贴图&#xff09;的应用&#xff0c;案例中使用 6 张不同的图片给立方体贴图&#xff0c;图片如下。 读者如果对 Filament 不太熟悉&#xff0c;请回顾以下内容。 Filament环境搭建绘制三角…

java调用GDAL实现栅格数据的重采样的一种方法

目录 1.关于重采样 1.1概念 1.2用途 1.3常见算法 2.关于GDAL 2.1GDAL中的重采样算法 3.实现重采样 3.1思路 3.2完整代码 3.3使用QGIS验证效果 1.关于重采样 1.1概念 重采样是以原始图像的像元值或者导出的值填充到新的图像的每个像元的的过程。 1.2用途 在地理信…

数据库开发表操作案例的详细解析

2.3.1.4 案例 需求&#xff1a;根据产品原型/需求创建表((设计合理的数据类型、长度、约束) 产品原型及需求如下&#xff1a; 步骤&#xff1a; 阅读产品原型及需求文档&#xff0c;看看里面涉及到哪些字段。 查看需求文档说明&#xff0c;确认各个字段的类型以及字段存储数据…

关于Python里xlwings库对Excel表格的操作(十七)

这篇小笔记主要记录如何【获取和设置单元格行高、列宽】。 前面的小笔记已整理成目录&#xff0c;可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】 &#xff08;1&#xff09;如何安装导入xlwings库&#xff1b; &#xff08;2&#xff09;如何在W…

【Python】pip管理Python包

命令&#xff1a;pip install <包名> 安装指定的包。 pip install ipython #或者 pip install ipython -i https://mirrors.aliyun.com/pypi/simple/ 命令&#xff1a;pip uninstall <包名> 删除指定的包。 pip uninstall ipython 命令&#xff1a;pip list 显…

SpringBoot2.x+mybatis plus3.x集成Activit7版本

文/朱季谦 在Activiti6版本当中&#xff0c;若要集成到Springboot里&#xff0c;需要写一些额外的配置类&#xff0c;我曾经在Activiti工作流框架学习笔记&#xff08;二&#xff09;之springboot2.0整合工作流Activiti6.0一文当中总结过相关配置过程&#xff0c;感兴趣的同学…