力扣第 106 场双周赛题解
题目链接:https://leetcode.cn/contest/biweekly-contest-106/
# T1. 判断一个数是否迷人
链接:https://leetcode.cn/problems/check-if-the-number-is-fascinating/
# 解题思路
hash 计数:
统计每一位数组出现的次数
# 代码
class Solution { | |
public boolean isFascinating(int n) { | |
int[] cnt = new int[10]; | |
calc(n, cnt); | |
calc(2 * n, cnt); | |
calc(3 * n, cnt); | |
for (int i = 1; i < 10; ++i) { | |
if (cnt[i] != 1) return false; | |
} | |
return true; | |
} | |
private void calc(int n, int[] cnt) { | |
while (n > 0) { | |
++cnt[n % 10]; | |
n /= 10; | |
} | |
} | |
} |
# T2. 找到最长的半重复子字符串
链接:https://leetcode.cn/problems/find-the-longest-semi-repetitive-substring/description/
# 解题思路
滑动窗口:
- 首先记录所有的重复位置
- 对重复位置进行枚举统计(从第二个重复位置开始)
具体看代码注释
# 代码
class Solution { | |
public int longestSemiRepetitiveSubstring(String s) { | |
int n = s.length(); | |
if (n < 3) return n; | |
// 记录重复的位置下标 | |
int[] repeat = new int[n - 1]; | |
// 重复位置下标的数量 | |
int cnt = 0; | |
for (int i = 0; i < n - 1; ++i) { | |
if (s.charAt(i) == s.charAt(i + 1)) { | |
repeat[cnt++] = i; | |
} | |
} | |
// 只有一个重复位置,直接返回原字符串的长度 | |
if (cnt < 2) return n; | |
// 有 n-1 个重复位置,说明是相同字符串组成的字符串 | |
if (cnt == n - 1) return 2; | |
// 当前的起始位置 | |
int pre = 0; | |
int ans = 0; | |
// 对重复位置进行枚举统计 | |
// 从第二个重复位置开始(允许有一个重复位置存在) | |
for (int i = 1; i < cnt; ++i) { | |
ans = Math.max(ans, repeat[i] - pre + 1); | |
// 跳过前一个重复的位置 | |
pre = repeat[i - 1] + 1; | |
} | |
// 最后一段也要处理 | |
return Math.max(ans, n - pre); | |
} | |
} |
# T3.
链接: