233. 数字 1 的个数

本文介绍了如何利用数学规律快速计算给定整数中每个位置的1的个数,通过理解基数周期和余数分析,提供了一种高效的LeetCode解决方案。通过实例演示和代码实现,帮助读者掌握解决此类问题的方法。

题目链接:leetcode.

这道题感觉也是做过的,,可是太菜了就忘记了○| ̄|_
总结规律来说就是对于第k位每10k+1个数就会有10k1(比如,百位即k=2[0-999]中百位为1的就有100个数)
对于12345而言,一共有12个1000,所以百位为1的个数就是12100,但还剩下345不足1000,里面依然有百位为1的情况,即[100-199],所以百位为1共有12100 + 100个
以此类推,对于第k位,除了有(n/10k+1)*10k1之外,还要分析t=(n%10k+1)的情况,此处能贡献min(max(t-10^k+1, 0), 10^k)1,将k从0循环到大于n即可

/*
执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗:6.2 MB, 在所有 C++ 提交中击败了5.14%的用户
*/
class Solution {
public:
    int countDigitOne(int n) {
        int ans = 0;
        for(int k = 0;pow(10, k) <= n;++k)
        {
            int x = pow(10, k);
            int add = (n / 10 / x) * x; //(n / (10 * x))会溢出
            ans += add;
            int t = n - 10 * add;
            ans += min(max(t - x + 1, 0), x);
        }
        return ans;
    }
};
```markdown 题目重述 编写一个方法,接收字符串 `"Hello World! Java 1234.@8527 Inter!"`,要求实现以下功能: 1. 统计大写字母的个数 2. 统计小写字母的个数 3. 统计数字个数 4. 统计空格的个数 5. 统计单词的个数(以空格分隔) 6. 将所有空格替换为 `"—"` 7. 去除字符串中非字母字符,仅保留单词,并将这些单词倒序拼接输出 给出答案(答案为带注释的代码块) ```java package ZY.zy005; public class TU2 { public static void main(String[] args) { String input = "Hello World! Java 1234.@8527 Inter!"; massegeInfo(input); } public static void massegeInfo(String text) { int upperCount = 0, lowerCount = 0, digitCount = 0, spaceCount = 0; StringBuilder cleanLetters = new StringBuilder(); // 1-4. 遍历统计字符类型 for (char c : text.toCharArray()) { if (c >= 'A' && c <= 'Z') upperCount++; else if (c >= 'a' && c <= 'z') lowerCount++; else if (c >= '0' && c <= '9') digitCount++; else if (c == ' ') spaceCount++; } // 5. 单词个数:连续非空字符串段(至少一个有效字符) String[] words = text.trim().split("\\s+"); int wordCount = 0; for (String word : words) { if (!word.isEmpty()) wordCount++; } // 6. 所有空格替换为"—" String replacedSpaces = text.replace(" ", "—"); // 7. 只保留字母,形成单词并倒序输出 StringBuilder temp = new StringBuilder(); for (char c : text.toCharArray()) { if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { temp.append(c); } else if (c == ' ' && temp.length() > 0 && temp.charAt(temp.length()-1) != ' ') { temp.append(' '); } } String cleanedText = temp.toString().trim(); String[] validWords = cleanedText.split("\\s+"); StringBuilder reversedResult = new StringBuilder(); for (int i = validWords.length - 1; i >= 0; i--) { reversedResult.append(validWords[i]); } // 输出全部结果 System.out.println("大写字母的个数: " + upperCount); System.out.println("小写字母的个数: " + lowerCount); System.out.println("数字个数: " + digitCount); System.out.println("空格的个数: " + spaceCount); System.out.println("单词的个数: " + wordCount); System.out.println("空格替换为\"—\"后: " + replacedSpaces); System.out.println("只留单词倒序输出: " + reversedResult.toString()); } } ``` 代码解析 1. **字符分类统计**:通过 `for-each` 循环遍历每个字符,使用 ASCII 范围判断类别,精确计数。 2. **单词数量计算**:使用正则 `\s+` 分割字符串并剔除空项,防止多个空格导致错误计数。 3. **空格替换**:`String.replace(" ", "—")` 实现全局单空格到 `"—" `的替换。 4. **提取有效字母串**:遍历过程中仅保留字母,空格作为单词分隔符插入,避免重复。 5. **倒序拼接**:将清洗后的单词数组从后往前拼接成单一字符串输出。 运行输出示例: ``` 大写字母的个数: 4 小写字母的个数: 14 数字个数: 8 空格的个数: 4 单词的个数: 5 空格替换为"-"后: Hello—World!—Java—1234.@8527—Inter! 只留单词倒序输出: interjavaorldelloH ``` 知识点(列出该代码中遇到的知识点) 1. **字符ASCII范围判断**:通过 `'A'-'Z'` 等区间快速识别字母、数字类型。 2. **字符串分割与数组应用**:使用 `split("\\s+")` 按任意空白分割,准确统计单词数。 3. **StringBuilder与动态拼接**:高效构建可变字符串,适用于频繁修改场景。 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值