G
N
I
D
A
O
L

力扣第 106 场双周赛题解

题目链接:https://leetcode.cn/contest/biweekly-contest-106/

# T1. 判断一个数是否迷人

链接:https://leetcode.cn/problems/check-if-the-number-is-fascinating/

# 解题思路

hash 计数:

统计每一位数组出现的次数

# 代码

a
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/

# 解题思路

滑动窗口:

  1. 首先记录所有的重复位置
  2. 对重复位置进行枚举统计(从第二个重复位置开始)

具体看代码注释

# 代码

a
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.

链接:

# 思路

# 代码

# 提交结果

更新于 阅读次数

😉觉得写的还不错,请我喝杯咖啡吧😁

独步凌波 微信支付

微信支付

独步凌波 支付宝

支付宝