文章目录
双周赛106
2729. 判断一个数是否迷人
难度简单0
给你一个三位数整数 n 。
如果经过以下修改得到的数字 恰好 包含数字 1 到 9 各一次且不包含任何 0 ,那么我们称数字 n 是 迷人的 :
- 将
n与数字2 * n和3 * n连接 。
如果 n 是迷人的,返回 true,否则返回 false 。
连接 两个数字表示把它们首尾相接连在一起。比方说 121 和 371 连接得到 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 ,这个字符串只包含 0 到 9 的数字字符。
如果一个字符串 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 取余后返回。
注意:
- 对于坐标在
i和j的两个机器人,(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 * 1090 <= d <= 109nums.length == s.lengths只包含'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;
}
}

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

被折叠的 条评论
为什么被折叠?



