小C的好数(算法解析) | 豆包MarsCode AI刷题

19 阅读3分钟

小C的好数

问题描述

小C对“好数”非常感兴趣,她定义一个不含前导零的正整数为“好数”,如果它的所有数位最多包含两种不同的数字。例如,数字 2323239111,和 101 都是好数。现在小C想知道,从1到nn之间有多少个好数。

例如:当n=110n=110时,所有的1位数、2位数,以及一些3位数(如 100101)都是好数,一共有102个。


测试样例

样例1:

输入:n = 110
输出:102

样例2:

输入:n = 1000
输出:352

样例3:

输入:n = 1
输出:1

问题描述

小C定义一个不含前导零的正整数为“好数”,如果它的所有数位最多包含两种不同的数字。我们需要计算从1到nn之间有多少个好数。

关键点

  1. 不含前导零:这意味着我们不需要处理前导零的情况,因为题目已经明确指出输入的数字不会包含前导零。
  2. 最多包含两种不同的数字:一个数是好数,当且仅当它的所有数位中最多有两种不同的数字。

示例分析

  • 样例1n = 110

    • 1位数:1到9,共9个。
    • 2位数:10到99,共90个。
    • 3位数:100到110,其中100和101是好数,共2个。
    • 总计:9 + 90 + 2 = 102个好数。
  • 样例2n = 1000

    • 1位数:1到9,共9个。
    • 2位数:10到99,共90个。
    • 3位数:100到999,需要进一步判断。
    • 总计:352个好数。

解题思路

  1. 遍历所有数字:从1到nn,逐一判断每个数字是否是好数。

  2. 判断好数

    • 将数字转换为字符串。
    • 使用集合(Set)来记录不同的数字。
    • 如果集合的大小超过2,则该数字不是好数。
    • 否则,该数字是好数。
  3. 计数:统计所有好数的数量。

数据结构与算法

  • 数据结构:使用集合(Set)来记录数字中出现的不同数字。
  • 算法:遍历从1到nn的所有数字,对每个数字进行判断,统计好数的数量。
import java.util.HashSet;  
import java.util.Set; 
public class Main {
    public static int solution(int n) {
        int count = 0;  
        for (int i = 1; i <= n; i++) {  
            if (isGoodNumber(i)) {  
                count++;  
            }  
        }  
        return count;  
    }  
  
    private static boolean isGoodNumber(int number) {  
        String str = Integer.toString(number);  
        Set<Character> digits = new HashSet<>();  
        for (char c : str.toCharArray()) {  
            digits.add(c);  
            if (digits.size() > 2) {  
                return false;  
            }  
        }  
        return !str.startsWith("0") && digits.size() <= 2;  
    } 

    public static void main(String[] args) {
        System.out.println(solution(110) == 102);
        System.out.println(solution(1000) == 352);
        System.out.println(solution(1) == 1);
    }
}

通过遍历和集合的使用,我们可以有效地判断每个数字是否是好数,并统计好数的数量。

1. 数据结构

  • 集合(Set)

    • 集合是一种不允许重复元素的数据结构。
    • 在这个题目中,我们使用HashSet来记录数字中出现的不同数字。
    • HashSetadd方法可以添加元素,并且如果元素已经存在,不会重复添加。
    • HashSetsize方法可以返回集合中元素的数量。

2. 字符串操作

  • 字符串转换

    • 使用Integer.toString(number)将整数转换为字符串。
    • 使用str.toCharArray()将字符串转换为字符数组,方便遍历每个字符。

3. 循环与条件判断

  • 循环

    • 使用for循环遍历从1到nn的所有数字。
    • 使用for-each循环遍历字符数组中的每个字符。
  • 条件判断

    • 使用if语句判断集合的大小是否超过2,如果是,则该数字不是好数。
    • 使用return语句返回判断结果。

4. 函数与方法

  • 函数定义

    • solution(int n):主函数,负责遍历从1到nn的所有数字,并统计好数的数量。
    • isGoodNumber(int number):辅助函数,负责判断一个数字是否是好数。
  • 方法调用

    • solution函数中调用isGoodNumber函数来判断每个数字是否是好数。