给你一个下标从 0 开始的字符串
num
,表示一个非负整数。在一次操作中,您可以选择
num
的任意一位数字并将其删除。请注意,如果你删除num
中的所有数字,则num
变为0
。返回最少需要多少次操作可以使
num
变成特殊数字。如果整数
x
能被25
整除,则该整数x
被认为是特殊数字。示例 1:
输入:num = "2245047" 输出:2 解释:删除数字 num[5] 和 num[6] ,得到数字 "22450" ,可以被 25 整除。 可以证明要使数字变成特殊数字,最少需要删除 2 位数字。示例 2:
输入:num = "2908305" 输出:3 解释:删除 num[3]、num[4] 和 num[6] ,得到数字 "2900" ,可以被 25 整除。 可以证明要使数字变成特殊数字,最少需要删除 3 位数字。示例 3:
输入:num = "10" 输出:1 解释:删除 num[0] ,得到数字 "0" ,可以被 25 整除。 可以证明要使数字变成特殊数字,最少需要删除 1 位数字。
今天看到这个题目也是非常的懵,不知道该怎么下手,难道要暴力模拟?有没有简便的方法?在心中思索片刻后还是决定暴力,我们来对这道题进行分析,能被25整除的数,一位数中只有0,两位数中有25 50 75 ,三位数以上如果可以被25整除,那么一定是以00、25、50、75结尾的,我们就可以遍历一遍这个数字字符串,每次遇到这些关键的数字就记录下它的下标,同时判断此时是否可以得到要求的字符串。
说一下解题思路:假设定义数组nums[10]来存放下标,初始化为-1
用一个大小为10的数组记录每个数字的下标,因为我们要从数字的末尾来判断是否是特殊字符串同时要求最少的操作,所以我们就贪心的从后往前遍历字符串
当遇到字符0时,判断nums[0]是否为有效值,如果有效,此时构成XXX00式的数字,可以被25整除,他俩中间的字符都是需要去掉的,即中间nums[0]-i-1个数字字符,当然我们并不需要真的在字符串中删除它,只要返回需要删除的长度即可,你以为这就是答案吗,错,因为我们判断的00并不一定在字符串的末尾,在0后面的数字字符也是需要去除的,即num.size()-nums[0]-1,加上中间需要去除的字符,这种情况的答案就是num.size()-i-2
以此类推,当遇到字符2时,我们要判断nums[5]是否为有效值,若有效答案同上即num.size()-i-2
当遇到字符5时,判断nums[0]是否有效,答案同上
当遇到字符7时,判断nums[5]是否有效,答案同上
你以为到这里就结束了吗?不!以上只是说题目给的字符串符合以上情况,如果没有以上的情况大家是不是以为直接返回字符串长度就够了,事实证明是不行的,例如 10 ,这个字符串不符合以上任何一种,直接返回长度就是2,而我们只需要去掉1就可以了,因为0是可以被25整除的,所以我们要做一个判断,如果字符串中出现过0,只需要去掉字符串长度-1个就可以了,下面上代码
class Solution {
public:
int minimumOperations(string num) {
int nums[10];//记录下标
memset(nums,-1,sizeof(nums));//初始化为-1
for(int i=num.size()-1;i>=0;i--)
{
if(num[i]=='0')
{
if(nums[0]!=-1)
return num.size()-2-i;
else
nums[0]=i;
}
if(num[i]=='5')
{
if(nums[0]!=-1)
return num.size()-2-i;
else
nums[5]=i;
}
if(num[i]=='2')
{
if(nums[5]!=-1)
return num.size()-2-i;
else
nums[2]=i;
}
if(num[i]=='7')
{
if(nums[5]!=-1)
return num.size()-2-i;
else
nums[7]=i;
}
}
if(nums[0]==-1)//特判
return num.size();
else
return num.size()-1;
}
};