Overflow in intermediate arithmetic
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given a string s consisting of digits. Perform the following operation repeatedly until the string has exactly two digits:
s, starting from the first digit, calculate a new digit as the sum of the two digits modulo 10.s with the sequence of newly calculated digits, maintaining the order in which they are computed.Return true if the final two digits in s are the same; otherwise, return false.
Example 1:
Input: s = "3902"
Output: true
Explanation:
s = "3902"(s[0] + s[1]) % 10 = (3 + 9) % 10 = 2(s[1] + s[2]) % 10 = (9 + 0) % 10 = 9(s[2] + s[3]) % 10 = (0 + 2) % 10 = 2s becomes "292"(s[0] + s[1]) % 10 = (2 + 9) % 10 = 1(s[1] + s[2]) % 10 = (9 + 2) % 10 = 1s becomes "11""11" are the same, the output is true.Example 2:
Input: s = "34789"
Output: false
Explanation:
s = "34789".s = "7157".s = "862".s = "48".'4' != '8', the output is false.Constraints:
3 <= s.length <= 105s consists of only digits.Problem summary: You are given a string s consisting of digits. Perform the following operation repeatedly until the string has exactly two digits: For each pair of consecutive digits in s, starting from the first digit, calculate a new digit as the sum of the two digits modulo 10. Replace s with the sequence of newly calculated digits, maintaining the order in which they are computed. Return true if the final two digits in s are the same; otherwise, return false.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Math
"3902"
"34789"
pascals-triangle)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3463: Check If Digits Are Equal in String After Operations II
class Solution {
// Same as 3461. Check If Digits Are Equal in String After Operations I
public boolean hasSameDigits(String s) {
final int n = s.length();
int num1 = 0;
int num2 = 0;
for (int i = 0; i + 1 < n; ++i) {
final int coefficient = nCMOD10(n - 2, i);
num1 += (coefficient * (s.charAt(i) - '0')) % 10;
num1 %= 10;
num2 += (coefficient * (s.charAt(i + 1) - '0')) % 10;
num2 %= 10;
}
return num1 == num2;
}
// Returns (n, k) % 10.
private int nCMOD10(int n, int k) {
final int mod2 = lucasTheorem(n, k, 2);
final int mod5 = lucasTheorem(n, k, 5);
int[][] lookup = {
{0, 6, 2, 8, 4}, // mod2 == 0
{5, 1, 7, 3, 9} // mod2 == 1
};
return lookup[mod2][mod5];
}
// Returns (n, k) % prime.
private int lucasTheorem(int n, int k, int prime) {
int res = 1;
while (n > 0 || k > 0) {
final int nMod = n % prime;
final int MOD = k % prime;
res *= nCk(nMod, MOD);
res %= prime;
n /= prime;
k /= prime;
}
return res;
}
// Returns (n, k).
private int nCk(int n, int k) {
int res = 1;
for (int i = 0; i < k; ++i) {
res *= (n - i);
res /= (i + 1);
}
return res;
}
}
// Accepted solution for LeetCode #3463: Check If Digits Are Equal in String After Operations II
package main
import "math/bits"
// https://space.bilibili.com/206214
const mod = 10
func pow(x, n int) int {
res := 1
for ; n > 0; n /= 2 {
if n%2 > 0 {
res = res * x % mod
}
x = x * x % mod
}
return res
}
const mx = 100_000
var f, invF, p2, p5 [mx + 1]int
func init() {
f[0] = 1
for i := 1; i <= mx; i++ {
x := i
// 2 的幂次
e2 := bits.TrailingZeros(uint(x))
x >>= e2
// 5 的幂次
e5 := 0
for x%5 == 0 {
e5++
x /= 5
}
f[i] = f[i-1] * x % mod
p2[i] = p2[i-1] + e2
p5[i] = p5[i-1] + e5
}
invF[mx] = pow(f[mx], 3) // 欧拉定理
for i := mx; i > 0; i-- {
x := i
x >>= bits.TrailingZeros(uint(x))
for x%5 == 0 {
x /= 5
}
invF[i-1] = invF[i] * x % mod
}
}
var pow2 = [4]int{2, 4, 8, 6}
func comb(n, k int) int {
res := f[n] * invF[k] * invF[n-k]
e2 := p2[n] - p2[k] - p2[n-k]
if e2 > 0 {
res *= pow2[(e2-1)%4]
}
if p5[n]-p5[k]-p5[n-k] > 0 {
res *= 5
}
return res
}
func hasSameDigits(s string) bool {
diff := 0
for i := range len(s) - 1 {
diff += comb(len(s)-2, i) * (int(s[i]) - int(s[i+1]))
}
return diff%mod == 0
}
# Accepted solution for LeetCode #3463: Check If Digits Are Equal in String After Operations II
class Solution:
# Same as 3461. Check If Digits Are Equal in String After Operations I
def hasSameDigits(self, s: str) -> bool:
n = len(s)
num1 = 0
num2 = 0
for i in range(n - 1):
coefficient = self._nCMOD10(n - 2, i)
num1 += (coefficient * (int(s[i]) - 0)) % 10
num1 %= 10
num2 += (coefficient * (int(s[i + 1]) - 0)) % 10
num2 %= 10
return num1 == num2
def _nCMOD10(self, n: int, k: int) -> int:
"""Returns (n, k) % 10."""
mod2 = self._lucasTheorem(n, k, 2)
mod5 = self._lucasTheorem(n, k, 5)
lookup = [
[0, 6, 2, 8, 4], # mod2 == 0
[5, 1, 7, 3, 9] # mod2 == 1
]
return lookup[mod2][mod5]
def _lucasTheorem(self, n: int, k: int, prime: int) -> int:
"""Returns (n, k) % prime."""
res = 1
while n > 0 or k > 0:
nMod = n % prime
MOD = k % prime
res *= math.comb(nMod, MOD)
res %= prime
n //= prime
k //= prime
return res
// Accepted solution for LeetCode #3463: Check If Digits Are Equal in String After Operations II
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #3463: Check If Digits Are Equal in String After Operations II
// class Solution {
// // Same as 3461. Check If Digits Are Equal in String After Operations I
// public boolean hasSameDigits(String s) {
// final int n = s.length();
// int num1 = 0;
// int num2 = 0;
//
// for (int i = 0; i + 1 < n; ++i) {
// final int coefficient = nCMOD10(n - 2, i);
// num1 += (coefficient * (s.charAt(i) - '0')) % 10;
// num1 %= 10;
// num2 += (coefficient * (s.charAt(i + 1) - '0')) % 10;
// num2 %= 10;
// }
//
// return num1 == num2;
// }
//
// // Returns (n, k) % 10.
// private int nCMOD10(int n, int k) {
// final int mod2 = lucasTheorem(n, k, 2);
// final int mod5 = lucasTheorem(n, k, 5);
// int[][] lookup = {
// {0, 6, 2, 8, 4}, // mod2 == 0
// {5, 1, 7, 3, 9} // mod2 == 1
// };
// return lookup[mod2][mod5];
// }
//
// // Returns (n, k) % prime.
// private int lucasTheorem(int n, int k, int prime) {
// int res = 1;
// while (n > 0 || k > 0) {
// final int nMod = n % prime;
// final int MOD = k % prime;
// res *= nCk(nMod, MOD);
// res %= prime;
// n /= prime;
// k /= prime;
// }
// return res;
// }
//
// // Returns (n, k).
// private int nCk(int n, int k) {
// int res = 1;
// for (int i = 0; i < k; ++i) {
// res *= (n - i);
// res /= (i + 1);
// }
// return res;
// }
// }
// Accepted solution for LeetCode #3463: Check If Digits Are Equal in String After Operations II
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #3463: Check If Digits Are Equal in String After Operations II
// class Solution {
// // Same as 3461. Check If Digits Are Equal in String After Operations I
// public boolean hasSameDigits(String s) {
// final int n = s.length();
// int num1 = 0;
// int num2 = 0;
//
// for (int i = 0; i + 1 < n; ++i) {
// final int coefficient = nCMOD10(n - 2, i);
// num1 += (coefficient * (s.charAt(i) - '0')) % 10;
// num1 %= 10;
// num2 += (coefficient * (s.charAt(i + 1) - '0')) % 10;
// num2 %= 10;
// }
//
// return num1 == num2;
// }
//
// // Returns (n, k) % 10.
// private int nCMOD10(int n, int k) {
// final int mod2 = lucasTheorem(n, k, 2);
// final int mod5 = lucasTheorem(n, k, 5);
// int[][] lookup = {
// {0, 6, 2, 8, 4}, // mod2 == 0
// {5, 1, 7, 3, 9} // mod2 == 1
// };
// return lookup[mod2][mod5];
// }
//
// // Returns (n, k) % prime.
// private int lucasTheorem(int n, int k, int prime) {
// int res = 1;
// while (n > 0 || k > 0) {
// final int nMod = n % prime;
// final int MOD = k % prime;
// res *= nCk(nMod, MOD);
// res %= prime;
// n /= prime;
// k /= prime;
// }
// return res;
// }
//
// // Returns (n, k).
// private int nCk(int n, int k) {
// int res = 1;
// for (int i = 0; i < k; ++i) {
// res *= (n - i);
// res /= (i + 1);
// }
// return res;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Simulate the process step by step — multiply n times, check each number up to n, or iterate through all possibilities. Each step is O(1), but doing it n times gives O(n). No extra space needed since we just track running state.
Math problems often have a closed-form or O(log n) solution hidden behind an O(n) simulation. Modular arithmetic, fast exponentiation (repeated squaring), GCD (Euclidean algorithm), and number theory properties can dramatically reduce complexity.
Review these before coding to avoid predictable interview regressions.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.