leetcode-2269. 找到一个数字的 K 美丽值
题目
一个整数 num
的 k 美丽值定义为 num
中符合以下条件的 子字符串 数目:
子字符串长度为
k
。子字符串能整除
num
。
给你整数 num
和 k
,请你返回 num
的 k 美丽值。
注意:
允许有 前缀 0 。
0
不能整除任何值。
一个 子字符串 是一个字符串里的连续一段字符序列。
示例
示例 1:
输入:num = 240, k = 2
输出:2
解释:以下是 num 里长度为 k 的子字符串:
- "240" 中的 "24" :24 能整除 240 。
- "240" 中的 "40" :40 能整除 240 。
所以,k 美丽值为 2 。
示例 2:
输入:num = 430043, k = 2
输出:2
解释:以下是 num 里长度为 k 的子字符串:
- "430043" 中的 "43" :43 能整除 430043 。
- "430043" 中的 "30" :30 不能整除 430043 。
- "430043" 中的 "00" :0 不能整除 430043 。
- "430043" 中的 "04" :4 不能整除 430043 。
- "430043" 中的 "43" :43 能整除 430043 。
所以,k 美丽值为 2 。
代码实现思路
一看到寻找子字符串,且定长为k。立马思路延续上一题思路leetcode-1456. 定长子串中元音的最大数目。
核心思路:整体单次遍历,滑动窗口左边出,右边进,通过StringBuilder 进行字符拼接并计算。
这一过程符合定长滑动数组的基本思路:入、更新(操作)、出。时间复杂度O(n)
实现代码如下:
public static int divisorSubstrings(int num, int k) {
char[] cs = String.valueOf(num).toCharArray();
int length = cs.length;
if (k > length){
return 0;
}
StringBuilder sb = new StringBuilder();
int x = 0;
int count = 0;
while (x < k) {
sb.append(cs[x]);
x++;
}
for (int i = k-1; i < length ; i++) {
int currNum = Integer.parseInt(sb.toString());
if (currNum != 0 && num % currNum == 0) {
count++;
}
sb.deleteCharAt(0);
if (i+1 ==length ) break;
sb.append(cs[i+1]);
}
return count;
}
总结
这种定长滑动数组的基本思路已经可以确定为:入、更新(操作)、出
再遇到类似的也应该换汤不换药了,我觉得这种题的难点是在于如何界定边界值,例如入窗和出窗的下标计算,不过这个可以通过数学规律找出。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 DoublePeach
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果