📜  求第k个最小的数字,且数字的总和为m

📅  最后修改于: 2021-04-24 16:26:46             🧑  作者: Mango

给定两个整数MK ,任务是找到数字和为M第K个最小数字。

例子:

方法:我们需要找到从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