LeetCode 2269: Find the K-Beauty of a Number (Fixed-Length Sliding Window + Divisibility Check)
LeetCode 2269Sliding WindowMathToday we solve LeetCode 2269 - Find the K-Beauty of a Number.
Source: https://leetcode.com/problems/find-the-k-beauty-of-a-number/
English
Problem Summary
Given an integer num and an integer k, consider every contiguous substring of length k in num's decimal representation. A substring is valid if its integer value is non-zero and divides num. Return the number of valid substrings.
Key Idea
Because all windows have equal length, we can scan from left to right and evaluate each window once. For each substring value x, count it only when x != 0 and num % x == 0.
Algorithm
1) Convert num to string s.
2) For every start index i from 0 to s.length - k:
- parse s[i..i+k-1] into integer x
- if x != 0 and num % x == 0, increase answer.
3) Return answer.
Complexity
Let n be digit length of num. We process n-k+1 windows, each parsing k digits. Time complexity is O((n-k+1) * k), space complexity is O(1) besides the string.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int divisorSubstrings(int num, int k) {
String s = String.valueOf(num);
int ans = 0;
for (int i = 0; i + k <= s.length(); i++) {
int x = Integer.parseInt(s.substring(i, i + k));
if (x != 0 && num % x == 0) {
ans++;
}
}
return ans;
}
}import "strconv"
func divisorSubstrings(num int, k int) int {
s := strconv.Itoa(num)
ans := 0
for i := 0; i+k <= len(s); i++ {
x, _ := strconv.Atoi(s[i : i+k])
if x != 0 && num%x == 0 {
ans++
}
}
return ans
}class Solution {
public:
int divisorSubstrings(int num, int k) {
string s = to_string(num);
int ans = 0;
for (int i = 0; i + k <= (int)s.size(); ++i) {
int x = stoi(s.substr(i, k));
if (x != 0 && num % x == 0) {
++ans;
}
}
return ans;
}
};class Solution:
def divisorSubstrings(self, num: int, k: int) -> int:
s = str(num)
ans = 0
for i in range(len(s) - k + 1):
x = int(s[i:i + k])
if x != 0 and num % x == 0:
ans += 1
return ansvar divisorSubstrings = function(num, k) {
const s = String(num);
let ans = 0;
for (let i = 0; i + k <= s.length; i++) {
const x = Number(s.slice(i, i + k));
if (x !== 0 && num % x === 0) {
ans++;
}
}
return ans;
};中文
题目概述
给定整数 num 和整数 k,把 num 看成字符串后,枚举所有长度为 k 的连续子串。若子串对应整数 x 非 0 且能整除 num,则该子串有效。返回有效子串数量。
核心思路
窗口长度固定为 k,直接从左到右扫描每个窗口。每个窗口只做一次解析和一次整除判断,遇到 x=0 直接跳过避免除零。
算法步骤
1)把 num 转成字符串 s。
2)枚举起点 i(0 <= i <= len(s)-k)。
3)取子串 s[i:i+k] 转成整数 x。
4)若 x != 0 且 num % x == 0,计数加一。
5)返回计数结果。
复杂度分析
设 n 为 num 的位数。共有 n-k+1 个窗口,每次解析长度 k 的子串,总时间复杂度 O((n-k+1) * k);额外空间复杂度 O(1)(不计字符串存储)。
参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int divisorSubstrings(int num, int k) {
String s = String.valueOf(num);
int ans = 0;
for (int i = 0; i + k <= s.length(); i++) {
int x = Integer.parseInt(s.substring(i, i + k));
if (x != 0 && num % x == 0) {
ans++;
}
}
return ans;
}
}import "strconv"
func divisorSubstrings(num int, k int) int {
s := strconv.Itoa(num)
ans := 0
for i := 0; i+k <= len(s); i++ {
x, _ := strconv.Atoi(s[i : i+k])
if x != 0 && num%x == 0 {
ans++
}
}
return ans
}class Solution {
public:
int divisorSubstrings(int num, int k) {
string s = to_string(num);
int ans = 0;
for (int i = 0; i + k <= (int)s.size(); ++i) {
int x = stoi(s.substr(i, k));
if (x != 0 && num % x == 0) {
++ans;
}
}
return ans;
}
};class Solution:
def divisorSubstrings(self, num: int, k: int) -> int:
s = str(num)
ans = 0
for i in range(len(s) - k + 1):
x = int(s[i:i + k])
if x != 0 and num % x == 0:
ans += 1
return ansvar divisorSubstrings = function(num, k) {
const s = String(num);
let ans = 0;
for (let i = 0; i + k <= s.length; i++) {
const x = Number(s.slice(i, i + k));
if (x !== 0 && num % x === 0) {
ans++;
}
}
return ans;
};
Comments