Given a positive integer n and an integer d, find the total count of numbers in the range [1, n] such that the difference between the number and the sum of its digits is greater than or equal to the specified value d.
Examples:
Input : n = 13, d = 2
Output : 4
Explanation: 10, 11, 12 and 13 satisfy the given condition:
10 : 10 - digitSum(10) = 9 >= 2
11 : 11 - digitSum(11) = 9 >= 2
12 : 12 - digitSum(12) = 9 >= 2
13 : 13 - digitSum(13) = 9 >= 2Input: n = 14, d = 3
Output: 5
Explanation: Numbers 10, 11, 12, 13, 14 satisfy the given condition.
Table of Content
[Naive Approach] Using Linear Search - O(n) time and O(1) space
The idea is to check for each integer in the range [1, n] if the difference between the integer and sum of its digits is less than equal to d.
#include <iostream>
using namespace std;
int getCount(int n, int d) {
int res = 0;
// Check for each value in range
for (int i=1; i<=n; i++) {
int val = i;
int digitSum = 0;
// Find sum of digits
while (val > 0) {
digitSum += val%10;
val = val/10;
}
if (i - digitSum >= d) res++;
}
return res;
}
int main() {
int n = 13, d = 2;
cout << getCount(n, d);
return 0;
}
class GfG {
static int getCount(int n, int d) {
int res = 0;
// Check for each value in range
for (int i = 1; i <= n; i++) {
int val = i;
int digitSum = 0;
// Find sum of digits
while (val > 0) {
digitSum += val % 10;
val = val / 10;
}
if (i - digitSum >= d) res++;
}
return res;
}
public static void main(String[] args) {
int n = 13, d = 2;
System.out.println(getCount(n, d));
}
}
def getCount(n, d):
res = 0
# Check for each value in range
for i in range(1, n + 1):
val = i
digitSum = 0
# Find sum of digits
while val > 0:
digitSum += val % 10
val = val // 10
if i - digitSum >= d:
res += 1
return res
if __name__ == "__main__":
n = 13
d = 2
print(getCount(n, d))
using System;
class GfG {
static int getCount(int n, int d) {
int res = 0;
// Check for each value in range
for (int i = 1; i <= n; i++) {
int val = i;
int digitSum = 0;
// Find sum of digits
while (val > 0) {
digitSum += val % 10;
val = val / 10;
}
if (i - digitSum >= d) res++;
}
return res;
}
static void Main(string[] args) {
int n = 13, d = 2;
Console.WriteLine(getCount(n, d));
}
}
function getCount(n, d) {
let res = 0;
// Check for each value in range
for (let i = 1; i <= n; i++) {
let val = i;
let digitSum = 0;
// Find sum of digits
while (val > 0) {
digitSum += val % 10;
val = Math.floor(val / 10);
}
if (i - digitSum >= d) res++;
}
return res;
}
//Driver Code
let n = 13, d = 2;
console.log(getCount(n, d));
Output
4
[Expected Approach] Using Binary Search - O(log n) time and O(1) space
The idea is to use binary search to efficiently find the smallest number
ksuch that the difference betweenkand the sum of its digits is greater than or equal tod.
Suppose for some integer k, the condition k - digitSum(k) >= d holds. Now consider any integer k' > k. Since k' > k, the numeric value has increased, and while the digit sum digitSum(k') may increase as well, it increases much slower than k' because each digit can only contribute at most 9.
Therefore, the gap k' - digitSum(k') grows with increasing k'. This implies that if the condition holds for k, it must also hold for any k' > k, making the predicate monotonic and thus suitable for binary search.
#include <iostream>
using namespace std;
// Function to check if difference between
// value n and sum of digits is greater
// than equal to d.
bool isGreater(int val, int d) {
int digitSum = 0, tmp = val;
while (tmp>0) {
digitSum += tmp%10;
tmp /= 10;
}
return val - digitSum >= d;
}
int getCount(int n, int d) {
// Minimum number for which difference between
// number and sum of digits >= d.
int mini = n + 1;
int s = 1, e = n;
while (s<=e) {
int mid = s + (e-s)/2;
if (isGreater(mid, d)) {
mini = mid;
e = mid - 1;
}
else s = mid + 1;
}
// Number of values in range [1, n]
// will be equal to
return n+1-mini;
}
int main() {
int n = 13, d = 2;
cout << getCount(n, d);
return 0;
}
class GfG {
// Function to check if difference between
// value n and sum of digits is greater
// than equal to d.
static boolean isGreater(int val, int d) {
int digitSum = 0, tmp = val;
while (tmp > 0) {
digitSum += tmp % 10;
tmp /= 10;
}
return val - digitSum >= d;
}
static int getCount(int n, int d) {
// Minimum number for which difference between
// number and sum of digits >= d.
int mini = n + 1;
int s = 1, e = n;
while (s <= e) {
int mid = s + (e - s) / 2;
if (isGreater(mid, d)) {
mini = mid;
e = mid - 1;
}
else s = mid + 1;
}
// Number of values in range [1, n]
// will be equal to
return n + 1 - mini;
}
public static void main(String[] args) {
int n = 13, d = 2;
System.out.println(getCount(n, d));
}
}
# Function to check if difference between
# value n and sum of digits is greater
# than equal to d.
def isGreater(val, d):
digitSum = 0
tmp = val
while tmp > 0:
digitSum += tmp % 10
tmp //= 10
return val - digitSum >= d
def getCount(n, d):
# Minimum number for which difference between
# number and sum of digits >= d.
mini = n + 1
s = 1
e = n
while s <= e:
mid = s + (e - s) // 2
if isGreater(mid, d):
mini = mid
e = mid - 1
else:
s = mid + 1
# Number of values in range [1, n]
# will be equal to
return n + 1 - mini
if __name__ == "__main__":
n = 13
d = 2
print(getCount(n, d))
using System;
class GfG {
// Function to check if difference between
// value n and sum of digits is greater
// than equal to d.
static bool isGreater(int val, int d) {
int digitSum = 0, tmp = val;
while (tmp > 0) {
digitSum += tmp % 10;
tmp /= 10;
}
return val - digitSum >= d;
}
static int getCount(int n, int d) {
// Minimum number for which difference between
// number and sum of digits >= d.
int mini = n + 1;
int s = 1, e = n;
while (s <= e) {
int mid = s + (e - s) / 2;
if (isGreater(mid, d)) {
mini = mid;
e = mid - 1;
}
else s = mid + 1;
}
// Number of values in range [1, n]
// will be equal to
return n + 1 - mini;
}
static void Main(string[] args) {
int n = 13, d = 2;
Console.WriteLine(getCount(n, d));
}
}
// Function to check if difference between
// value n and sum of digits is greater
// than equal to d.
function isGreater(val, d) {
let digitSum = 0, tmp = val;
while (tmp > 0) {
digitSum += tmp % 10;
tmp = Math.floor(tmp / 10);
}
return val - digitSum >= d;
}
function getCount(n, d) {
// Minimum number for which difference between
// number and sum of digits >= d.
let mini = n + 1;
let s = 1, e = n;
while (s <= e) {
let mid = Math.floor(s + (e - s) / 2);
if (isGreater(mid, d)) {
mini = mid;
e = mid - 1;
} else {
s = mid + 1;
}
}
// Number of values in range [1, n]
// will be equal to
return n + 1 - mini;
}
let n = 13, d = 2;
console.log(getCount(n, d));
Output
4