给定两个整数M和K ,任务是找到数字和为M的第K个最小数字。
例子:
Input: M = 5, K = 3
Output: 23
Sequence of numbers starting from 1 with digit sum as 5 is as follows:
5
14
23
32
41
So 3rd smallest number is 23
Input: M = 4, K = 1
Output: 4
方法:我们需要找到从1开始的数字序列,其数字总和为m。
- 编写一个递归函数,该函数将增加数字,直到该数字的总和等于我们要求的总和M为止。
- 为此,请始终从0开始,并检查将累加到M的个位数
- 让我们以sum = 5的示例为例,因为6超出了所需的总和,所以我们将从0开始并以一位数增加到5
- 现在从5开始,我们将移动到两位数字10,然后上升到14,因为14的数字总和为5,而15的数字将超过要求的总和,依此类推,然后我们再移20,然后继续上升到50,因为在50到99之后,每个数字的数字总和将大于5,因此我们将其跳过。
- 现在,我们将移动三位数字100、101、102 …,类似地,此操作将一直进行到数字的总和等于15为止。
- 我们将继续将元素插入到数字总和等于M的集合中。
下面是递归的代码:
for(int i=0;i<=min(left, 9LL);i++){
dfs(num*10+i, left-i, ct+1);
}
为了找到第k个最小的数字,我们需要对序列进行排序,因此最好将数字存储在C++中,因为集合中的数字是按排序的顺序排列的。
请注意,这种方法不适用于较大的输入值。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define int long long
const int N = 2005;
set ans;
// Recursively moving to add
// all the numbers upto a limit
// with sum of digits as m
void dfs(int num, int left, int ct)
{
// Max number of digits allowed in
// a number for this implementation
if (ct >= 15)
return;
if (left == 0)
ans.insert(num);
for (int i = 0; i <= min(left, 9LL); i++)
dfs(num * 10 + i, left - i, ct + 1);
}
// Function to return the kth number
// with sum of digits as m
int getKthNum(int m, int k)
{
dfs(0, m, 0);
int ct = 0;
for (auto it : ans) {
ct++;
// The kth smallest number is found
if (ct == k) {
return it;
}
}
return -1;
}
// Driver code
int main()
{
int m = 5, k = 3;
cout << getKthNum(m, k);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
static int N = 2005;
static Set ans = new LinkedHashSet();
// Recursively moving to add
// all the numbers upto a limit
// with sum of digits as m
static void dfs(int num, int left, int ct)
{
// Max number of digits allowed in
// a number for this implementation
if (ct >= 15)
return;
if (left == 0)
ans.add(num);
for (int i = 0; i <= Math.min(left, 9); i++)
dfs(num * 10 + i, left - i, ct + 1);
}
// Function to return the kth number
// with sum of digits as m
static int getKthNum(int m, int k)
{
dfs(0, m, 0);
int ct = 0;
for (int it : ans)
{
ct++;
// The kth smallest number is found
if (ct == k)
{
return it;
}
}
return -1;
}
// Driver code
public static void main(String[] args)
{
int m = 5, k = 3;
System.out.println(getKthNum(m, k));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
# define long long
N = 2005
ans = dict()
# Recursively moving to add
# all the numbers upto a limit
# with sum of digits as m
def dfs(n, left, ct):
# Max nber of digits allowed in
# a nber for this implementation
if (ct >= 15):
return
if (left == 0):
ans[n] = 1
for i in range(min(left, 9) + 1):
dfs(n * 10 + i, left - i, ct + 1)
# Function to return the kth number
# with sum of digits as m
def getKthNum(m, k):
dfs(0, m, 0)
c = 0
for it in sorted(ans.keys()):
c += 1
# The kth smallest number is found
if (c == k):
return it
return -1
# Driver code
m = 5
k = 3
print(getKthNum(m, k))
# This code is contributed by Mohit Kumar
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
static int N = 2005;
static HashSet ans = new HashSet();
// Recursively moving to add
// all the numbers upto a limit
// with sum of digits as m
static void dfs(int num, int left, int ct)
{
// Max number of digits allowed in
// a number for this implementation
if (ct >= 15)
return;
if (left == 0)
ans.Add(num);
for (int i = 0;
i <= Math.Min(left, 9); i++)
dfs(num * 10 + i, left - i, ct + 1);
}
// Function to return the kth number
// with sum of digits as m
static int getKthNum(int m, int k)
{
dfs(0, m, 0);
int ct = 0;
foreach (int it in ans)
{
ct++;
// The kth smallest number is found
if (ct == k)
{
return it;
}
}
return -1;
}
// Driver code
public static void Main(String[] args)
{
int m = 5, k = 3;
Console.WriteLine(getKthNum(m, k));
}
}
// This code is contributed by 29AjayKumar
输出:
23