leetcode
leetcode 2401 ~ 2450
生成特殊数字的最少操作

生成特殊数字的最少操作

难度:

标签:

题目描述

You are given a 0-indexed string num representing a non-negative integer.

In one operation, you can pick any digit of num and delete it. Note that if you delete all the digits of num, num becomes 0.

Return the minimum number of operations required to make num special.

An integer x is considered special if it is divisible by 25.

 

Example 1:

Input: num = "2245047"
Output: 2
Explanation: Delete digits num[5] and num[6]. The resulting number is "22450" which is special since it is divisible by 25.
It can be shown that 2 is the minimum number of operations required to get a special number.

Example 2:

Input: num = "2908305"
Output: 3
Explanation: Delete digits num[3], num[4], and num[6]. The resulting number is "2900" which is special since it is divisible by 25.
It can be shown that 3 is the minimum number of operations required to get a special number.

Example 3:

Input: num = "10"
Output: 1
Explanation: Delete digit num[0]. The resulting number is "0" which is special since it is divisible by 25.
It can be shown that 1 is the minimum number of operations required to get a special number.

 

Constraints:

  • 1 <= num.length <= 100
  • num only consists of digits '0' through '9'.
  • num does not contain any leading zeros.

代码结果

运行时间: 27 ms, 内存: 16.1 MB


/*
 * 思路:
 * 1. 使用Java Stream来简化组合的生成。
 * 2. 枚举所有可能的数字组合并检查能否被25整除。
 * 3. 找到组合所需的最小删除次数。
 */
import java.util.stream.IntStream;

public class SpecialNumberStream {
    public int minDeletions(String num) {
        int n = num.length();
        return IntStream.range(0, n)
                .flatMap(i -> IntStream.range(i + 1, n)
                        .map(j -> {
                            String subNum = num.substring(0, i) + num.substring(i + 1, j) + num.substring(j + 1);
                            return subNum.length() > 0 && Integer.parseInt(subNum) % 25 == 0 ? 2 : n;
                        }))
                .min().orElse(n);
    }

    public static void main(String[] args) {
        SpecialNumberStream sn = new SpecialNumberStream();
        System.out.println(sn.minDeletions("2245047")); // 输出 2
        System.out.println(sn.minDeletions("2908305")); // 输出 3
        System.out.println(sn.minDeletions("10")); // 输出 1
    }
}

解释

方法:

该题解的基本思路是找到构成可以被25整除的数字的最少删除操作数。考虑到一个数字如果以00, 25, 50, 75结尾则可以被25整除。算法首先检查是否存在单个0,如果存在,则可以通过删除所有其他数字使其为0,这是删除最少的情况之一。然后,分别检查以5和0结尾的情况。对于以5结尾的情况,向前搜索直到找到2或7,对于以0结尾的情况,向前搜索直到找到另一个0或5。这样可以保证找到的数字是以25, 50, 75, 00结尾的。最后返回所有情况中删除数目最少的结果。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
在算法中,为什么首先检查是否存在单个'0',并假设删除所有其他数字后只留一个'0'就是最优解?
这种情况考虑的是最简单直接的解法。因为如果一个数字可以简单地通过删除其他所有数字只留下一个'0',那么这个数字就能被25整除(因为0是25的倍数)。这种方法通常会涉及最少的删除操作,因为只需要保留一个字符,所以算法首先尝试这种简便的方式。
🦆
对于以'5'结尾的数字寻找'2'或'7'时,如果字符串中不存在'2'或'7',算法会如何处理?
如果在字符串中以'5'结尾后向前搜索并未找到'2'或'7',则这种情况下,以25或75结尾的组合不可能形成,算法将不会考虑以'5'结尾的数作为一个有效的结尾组合。在这种情况下,算法会继续探索其他可能的组合(如以'00', '50'结尾的情况)。
🦆
算法在寻找以'0'或'5'结尾的组合时的边界处理是怎样的?例如,如果'5'或'0'位于字符串的最开始位置,应该如何操作?
如果'5'或'0'位于字符串的最开始(即索引为0的位置),那么它前面没有其他数字可以形成有效的组合(如25, 50, 75)。在这种情况下,算法不会考虑这样的'5'或'0'作为有效的结尾组合。算法需要至少一个在'5'或'0'前面的数字来形成一个可以被25整除的两位数。
🦆
在算法描述中,提到了将所有其他数删除只留下一个'0'的操作,这种情况下是否考虑了原字符串只包含一个'0'的情况?
是的,如果原字符串只包含一个'0',这实际上是最理想的情况之一,因为不需要进行任何删除操作。算法中提到的将所有其他数删除只留下一个'0'的操作是为了处理包含多个数字的情况,但如果字符串本来就只有一个'0',则不需要任何删除,直接返回0即可。

相关问题