难度简单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;
}
}
难度中等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;
}
}
难度中等8
有一些机器人分布在一条无限长的数轴上,他们初始坐标用一个下标从 0 开始的整数数组 nums
表示。当你给机器人下达命令时,它们以每秒钟一单位的速度开始移动。
给你一个字符串 s
,每个字符按顺序分别表示每个机器人移动的方向。'L'
表示机器人往左或者数轴的负方向移动,'R'
表示机器人往右或者数轴的正方向移动。
当两个机器人相撞时,它们开始沿着原本相反的方向移动。
请你返回指令重复执行 d
秒后,所有机器人之间两两距离之和。由于答案可能很大,请你将答案对 109 + 7
取余后返回。
注意:
i
和 j
的两个机器人,(i,j)
和 (j,i)
视为相同的坐标对。也就是说,机器人视为无差别的。示例 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;
}
}