双周赛106(模拟、双指针、脑经急转弯+贡献法)

文章介绍了LeetCode双周赛中的三道编程题目,包括判断一个数是否迷人,找到最长的半重复子字符串以及移动机器人的问题。解题策略涉及模拟、双指针和数学计算,提供了Java和Python的解决方案。
部署运行你感兴趣的模型镜像

双周赛106

2729. 判断一个数是否迷人

难度简单0

给你一个三位数整数 n

如果经过以下修改得到的数字 恰好 包含数字 19 各一次且不包含任何 0 ,那么我们称数字 n迷人的

  • n 与数字 2 * n3 * n 连接

如果 n 是迷人的,返回 true,否则返回 false

连接 两个数字表示把它们首尾相接连在一起。比方说 121371 连接得到 121371

示例 1:

输入:n = 192
输出:true
解释:我们将数字 n = 192 ,2 * n = 384 和 3 * n = 576 连接,得到 192384576 。这个数字包含 1 到 9 恰好各一次。

示例 2:

输入:n = 100
输出:false
解释:我们将数字 n = 100 ,2 * n = 200 和 3 * n = 300 连接,得到 100200300 。这个数字不符合上述条件。

提示:

  • 100 <= n <= 999

模拟

不一定真的要拼接起来,只需要得到每位数字就行

class Solution {
    public boolean isFascinating(int n) {
        int a = 2 * n;
        int b = 3 * n;
        List<Integer> list = new ArrayList<>();
        while(n != 0){
            list.add(n % 10);
            n = n / 10;
        }
        while(a != 0){
            list.add(a % 10);
            a = a / 10;
        }
        while(b != 0){
            list.add(b % 10);
            b = b / 10;
        }
        Set<Integer> set = new HashSet<>();
        for(int num : list){
            if(set.contains(num) || num == 0)
                return false;
            set.add(num);
        }
        return set.size() == 9 ? true : false;
    }
}

2730. 找到最长的半重复子字符串

难度中等3

给你一个下标从 0 开始的字符串 s ,这个字符串只包含 09 的数字字符。

如果一个字符串 t 中至多有一对相邻字符是相等的,那么称这个字符串是 半重复的

请你返回 s 中最长 半重复 子字符串的长度。

一个 子字符串 是一个字符串中一段连续 非空 的字符。

示例 1:

输入:s = "52233"
输出:4
解释:最长半重复子字符串是 "5223" ,子字符串从 i = 0 开始,在 j = 3 处结束。

示例 2:

输入:s = "5494"
输出:4
解释:s 就是一个半重复字符串,所以答案为 4 。

示例 3:

输入:s = "1111111"
输出:2
解释:最长半重复子字符串是 "11" ,子字符串从 i = 0 开始,在 j = 1 处结束。

提示:

  • 1 <= s.length <= 50
  • '0' <= s[i] <= '9'

双指针

https://leetcode.cn/problems/find-the-longest-semi-repetitive-substring/solution/shuang-zhi-zhen-hua-chuang-pythonjavacgo-nurf/

移动右指针 right,并统计相邻相同的情况出现了多少次,记作 same如果 same >1,则不断移动左指针 left 直到 s[left] = s[left] - 1,此时将一对相同的字符移到窗口之外。然后将 same 置为 1。然后统计子串长度 right - left + 1 的最大值

class Solution {
    public int longestSemiRepetitiveSubstring(String S) {
        char[] s = S.toCharArray();
        int ans = 1, left = 0, same = 0, n = s.length;
        for(int right = 1; right < n; right++){
            if(s[right] == s[right-1]){
                same += 1;
                if(same > 1){
                    for(left += 1; s[left] != s[left-1]; left++);
                    same = 1;
                }
            }
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }
}

2731. 移动机器人

难度中等8

有一些机器人分布在一条无限长的数轴上,他们初始坐标用一个下标从 0 开始的整数数组 nums 表示。当你给机器人下达命令时,它们以每秒钟一单位的速度开始移动。

给你一个字符串 s ,每个字符按顺序分别表示每个机器人移动的方向。'L' 表示机器人往左或者数轴的负方向移动,'R' 表示机器人往右或者数轴的正方向移动。

当两个机器人相撞时,它们开始沿着原本相反的方向移动。

请你返回指令重复执行 d 秒后,所有机器人之间两两距离之和。由于答案可能很大,请你将答案对 109 + 7 取余后返回。

注意:

  • 对于坐标在 ij 的两个机器人,(i,j)(j,i) 视为相同的坐标对。也就是说,机器人视为无差别的。
  • 当机器人相撞时,它们 立即改变 它们的前进时间,这个过程不消耗任何时间。
  • 当两个机器人在同一时刻占据相同的位置时,就会相撞。
    • 例如,如果一个机器人位于位置 0 并往右移动,另一个机器人位于位置 2 并往左移动,下一秒,它们都将占据位置 1,并改变方向。再下一秒钟后,第一个机器人位于位置 0 并往左移动,而另一个机器人位于位置 2 并往右移动。
    • 例如,如果一个机器人位于位置 0 并往右移动,另一个机器人位于位置 1 并往左移动,下一秒,第一个机器人位于位置 0 并往左行驶,而另一个机器人位于位置 1 并往右移动。

示例 1:

输入:nums = [-2,0,2], s = "RLL", d = 3
输出:8
解释:
1 秒后,机器人的位置为 [-1,-1,1] 。现在下标为 0 的机器人开始往左移动,下标为 1 的机器人开始往右移动。
2 秒后,机器人的位置为 [-2,0,0] 。现在下标为 1 的机器人开始往左移动,下标为 2 的机器人开始往右移动。
3 秒后,机器人的位置为 [-3,-1,1] 。
下标为 0 和 1 的机器人之间距离为 abs(-3 - (-1)) = 2 。
下标为 0 和 2 的机器人之间的距离为 abs(-3 - 1) = 4 。
下标为 1 和 2 的机器人之间的距离为 abs(-1 - 1) = 2 。
所有机器人对之间的总距离为 2 + 4 + 2 = 8 。

示例 2:

输入:nums = [1,0], s = "RL", d = 2
输出:5
解释:
1 秒后,机器人的位置为 [2,-1] 。
2 秒后,机器人的位置为 [3,-2] 。
两个机器人的距离为 abs(-2 - 3) = 5 。

提示:

  • 2 <= nums.length <= 105
  • -2 * 109 <= nums[i] <= 2 * 109
  • 0 <= d <= 109
  • nums.length == s.length
  • s 只包含 'L''R'
  • nums[i] 互不相同。

脑筋急转弯

https://leetcode.cn/problems/movement-of-robots/solution/nao-jin-ji-zhuan-wan-pai-xu-tong-ji-pyth-we55/

class Solution {
    /**
    题目最后要求机器人之间的距离,此时把任意两个机器人的位置交换,并不会对答案产生影响。
    既然如此,那么可以把机器人都看成是完全一样的,无法区分。

    相撞等价于机器人互相穿过对方,因为我们无法区分机器人。 所以可以无视相撞的规则,把每个机器人都看成是独立运动的。
    类似的思路在 1503. 所有蚂蚁掉下来前的最后一刻 中出现过。
     */
    public int sumDistance(int[] nums, String s, int d) {
        final long MOD = (long) 1e9 + 7;
        int n = nums.length;
        var a = new long[n];
        for (int i = 0; i < n; i++) // 注意 2e9+1e9 溢出了
            a[i] = (long) nums[i] + d * ((s.charAt(i) & 2) - 1); // L=-1, R=1
        long ans = 0, sum = 0;
        Arrays.sort(a);
        // 从小到大枚举a[i],此时左边有i个数都不超过a[i], a[i]与其左侧机器人的距离之和为
        // a[i]-a[0] + (a[i]-a[1]) + ... + (a[i]-a[i-1]) = i * a[i] - (a[0] + a[1] + ... + a[i-1])
        for (int i = 0; i < n; i++) {
            ans = (ans + i * a[i] - sum) % MOD;
            sum += a[i];
        }
        return (int) ans;
    }
}

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

<think> 首先,用户的问题是关于理解一个特定的正则表达式:/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$。我需要解释这个正则表达式的含义。 回顾系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 最后,生成相关问题。 用户提供了三个引用: - 引用[1]:关于常见正则表达式,如正浮点数。 - 引用[2]:包含各种正则表达式的例子,如字母数字下划线字符串、整数、浮点数、中文字符、身份证号等。 - 引用[3]:关于正则表达式的简化建议。 但用户说这些引用仅供参考,我应该基于用户的问题来回答。用户的问题是解释正则表达式/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$的含义。 所以,我需要解析这个正则表达式。 分解正则表达式- /^:表示字符串的开始。 - (?=.*[A-Z]):这是一个正向先行断言(positive lookahead)。意思是:字符串中必须包含至少一个大写字母(A-Z)。 - (?=.*[a-z]):另一个正向先行断言,表示字符串中必须包含至少一个小写字母(a-z)。 - (?=.*[0-9]):另一个正向先行断言,表示字符串中必须包含至少一个数字(0-9)。 - .{8,}:表示任意字符(除换行符外)至少8次。意思是字符串长度至少为8个字符。 - $:表示字符串的结束。 所以,整体来看,这个正则表达式匹配的字符串必须: 1. 包含至少一个大写字母。 2. 包含至少一个小写字母。 3. 包含至少一个数字。 4. 长度至少为8个字符。 这通常用于密码强度验证,要求密码有大小写字母、数字,并且长度至少8位。 现在,构建回答: - 使用中文。 - 结构清晰:逐步解释。 - 引用相关部分:用户提供了引用,但它们是关于其他正则表达式的。我可以提到引用[2]中有类似的正则表达式例子,比如强密码的表达式,但用户的具体表达式不同。引用[2]中有类似的东西:/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$/,这很相似,但长度不同。 在引用[2]中:强密码:必须包含数字、字母,字符长度为6~15位 /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$/ 或 /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{6,15}$/。 用户的正则是/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$,长度至少8,没有上限,并且使用.*允许任何字符。 所以,在回答中,我可以引用这个。 引用[3]是关于简化正则表达式的建议,但可能不直接相关。 回答结构: 1. 介绍正则表达式的整体目的:用于验证密码强度。 2. 分解表达式部分: - ^$:表示整个字符串。 - (?=.*[A-Z]):解释先行断言的含义。 - 类似地解释其他部分。 - .{8,}:长度要求。 3. 总结匹配的条件。 4. 自然地添加引用:例如,在解释先行断言时,可以提到引用中的类似例子。 引用标识:在引用的段落末尾添加[^n]。 最后,生成相关问题。 相关问题应该基于这个主题,比如: 1. 如何使用这个正则表达式在代码中? 2. 这个正则表达式的局限性是什么? 3. 如何修改它来添加特殊字符要求? 4. 相关的正则表达式例子。 确保LaTeX:在回答中,如果有数学表达式,比如.*[A-Z],这不算数学表达式,所以不需要用$...$。但如果有像范围或计数,可能不需要。指令是针对数学表达式的,所以这里可能不适用。 在引用中,用户有像^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$这样的表达式,但没有要求用LaTeX格式。指令说“所有行内数学表达式(包括变量、不等式、方程等)必须使用$...$格式”,但正则表达式不是数学表达式,所以我应该直接写正则表达式。 在回答中,我会直接写正则表达式代码,用反引号表示代码块或内联代码。 指令有示例:在“快速排序”例子中,有代码块用```python```。 所以,我可以将正则表达式放入代码块。 回答步骤: 1. 解释整体含义。 2. 分解每个部分。 3. 给出示例匹配的字符串。 4. 引用相关资源。 5. 生成相关问题。 用中文。 </think> ### 正则表达式 `/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$` 的含义解析 这个正则表达式主要用于验证密码强度,要求字符串满足特定的复杂度条件。以下我将逐步分解其结构,帮助您理解每个部分的含义。整个表达式的核心是使用**正向先行断言(positive lookahead)** 来确保字符串中包含大写字母、小写字母和数字,同时要求最小长度。正则表达式语法可参考站内引用中的常见模式[^2]。 #### 1. **整体结构** - `/^ ... $/`:这表示正则表达式匹配整个字符串,从开头 (`^`) 到结尾 (`$`)。例如,字符串 `"Abc12345"` 会被匹配,但 `" Abc12345"`(开头有空格)则不会,因为空格导致开头不匹配。 - 表达式由多个部分组成: - 三个正向先行断言 `(?=...)`:用于检查字符串是否满足某些条件,但不消耗字符(即不移动匹配位置)。 - `.`:匹配任意单个字符(除换行符外)。 - `{8,}`:表示前面的模式(这里是 `.`)至少重复 8 次,即字符串长度至少为 8 个字符。 - **简言之**:这个正则表达式要求字符串**必须同时包含至少一个大写字母、至少一个小写字母、至少一个数字,且总长度不少于 8 个字符**。它常用于密码策略中,确保密码强度。 #### 2. **分解每个部分** - `(?=.*[A-Z])`: - `(?= ... )` 是正向先行断言,表示“字符串必须满足括号内的条件”,但不计入匹配位置。 - `.*`:匹配零个或多个任意字符(`.` 表示任意字符,`*` 表示重复零次或多次)。 - `[A-Z]`:匹配一个大写字母(A 到 Z)。 - **含义**:字符串中必须包含至少一个大写字母。例如,在 `"abc123"` 中不满足(没有大写字母),而 `"Abc123"` 满足。 - 类似用法在引用[2]中的“强密码”例子中出现过(如 `/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$/`)[^2]。 - `(?=.*[a-z])`: - 结构同上,但 `[a-z]` 匹配一个小写字母(a 到 z)。 - **含义**:字符串中必须包含至少一个小写字母。例如,`"ABC123"` 不满足(没有小写字母),而 `"Abc123"` 满足。 - `(?=.*[0-9])`: - `[0-9]` 匹配一个数字(09)。 - **含义**:字符串中必须包含至少一个数字。例如,`"Abcdefg"` 不满足(没有数字),而 `"Abc123"` 满足。 - `.{8,}`: - `.` 匹配任意字符。 - `{8,}` 表示前面的 `.` 至少重复 8 次,即字符串长度至少为 8 个字符。 - **含义**:整个字符串的最小长度为 8。例如,`"Abc123"`(长度 6)不满足,而 `"Abc12345"`(长度 8)满足。 #### 3. **组合效果和示例** - **匹配条件总结**: - 至少一个大写字母(A-Z)。 - 至少一个小写字母(a-z)。 - 至少一个数字(0-9)。 - 长度至少 8 个字符(允许更长)。 - 字符类型不限(因为 `.` 匹配任意字符,包括符号如 `!@#$`)。 - **有效匹配示例**: - `"Password123"`:包含大写 P、小写 assword、数字 123,长度 11。 - `"Abc!12345"`:包含大写 A、小写 bc、数字 12345,以及符号 `!`,长度 9- **无效匹配示例**: - `"password"`:缺少大写字母和数字。 - `"PASSWORD123"`:缺少小写字母。 - `"Abc123"`:长度不足 8。 - `"!@#$%^&*"`:缺少字母和数字。 这个表达式确保了密码的基础强度,但未要求特殊字符(如符号),您可以根据需求扩展。类似的正则表达式设计原则在引用[3]中提到,强调“宁简勿繁”,即拆解复杂条件为多个简单断言以提升可读性和效率[^3]。 #### 4. **实际应用** - 在编程中,这个正则表达式可用于表单验证(如密码输入框)。例如,在 JavaScript 中: ```javascript const regex = /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$/; console.log(regex.test("Abc12345")); // 输出 true console.log(regex.test("abc1234")); // 输出 false(缺少大写字母) ``` - 优点:使用先行断言能高效检查多个条件,无需嵌套或复杂逻辑。 - 局限性:它不检查字符类型重复(如多个数字),或特殊字符要求。如果需更严格规则(如包含符号),可追加断言,例如添加 `(?=.*[!@#$%^&*])`。 如果您有更多上下文(如具体代码实现),我可以提供更针对性的帮助。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值