📌  相关文章
📜  不超过 N 且不包含 S 的任何数字的最大数

📅  最后修改于: 2021-09-07 02:19:31             🧑  作者: Mango

给定一个数字字符串N ( 1 ≤ |N| ≤ 10 5 ) 和另一个数字字符串S ( 1 ≤ |S| ≤ 10 5 ),任务是找到最大数 ≤ N使得它不包含数字字符串S 。如果需要,删除前导零。
注意:字符串S不包含‘0’

例子:

朴素方法:对于N 的每个值,检查它是否包含S 的任何数字。继续将N1,直到S中出现的任何数字都不会出现在N 中
时间复杂度: O(|N| * log(|N|) * |S|)
辅助空间: O(1)

高效的方法:可以使用哈希优化上述方法。请按照以下步骤解决问题:

  1. 遍历字符串S的字符和S的不同字符存储在一个地图
  2. 遍历字符串N
  3. 如果发现N 的任何数字存在于S 中,比如idx数字,将N[idx]减少到S 中不存在的最大数字,比如LargestDig
  4. [idx + 1, |N|范围内的数字– 1]更改为LargestDig
  1. 从数字中删除所有前导零。

下面是上述方法的实现。

C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to obtain the largest number not exceeding
// num which does not contain any digits present in S
string greatestReducedNumber(string num, string s)
{
    // Stores digits of S
    vector vis_s(10, false);
 
    // Traverse the string S
    for (int i = 0; i < (int)s.size(); i++) {
 
        // Set occurrence as true
        vis_s[int(s[i]) - 48] = true;
    }
 
    int n = num.size();
    int in = -1;
 
    // Traverse the string n
    for (int i = 0; i < n; i++) {
        if (vis_s[(int)num[i] - '0']) {
            in = i;
            break;
        }
    }
 
    // All digits of num are not
    // present in string s
    if (in == -1) {
        return num;
    }
 
    for (char dig = num[in]; dig >= '0'; dig--) {
        if (vis_s[(int)dig - '0'] == 0) {
            num[in] = dig;
            break;
        }
    }
 
    char LargestDig = '0';
 
    for (char dig = '9'; dig >= '0'; dig--) {
        if (vis_s[dig - '0'] == false) {
 
            // Largest Digit not present
            // in the string s
            LargestDig = dig;
            break;
        }
    }
 
    // Set all digits from positions
    // in + 1 to n - 1 as LargestDig
    for (int i = in + 1; i < n; i++) {
        num[i] = LargestDig;
    }
 
    // Counting leading zeroes
    int Count = 0;
    for (int i = 0; i < n; i++) {
        if (num[i] == '0')
            Count++;
        else
            break;
    }
 
    // Removing leading zeroes
    num.erase(0, Count);
 
    // If the string becomes null
    if ((int)num.size() == 0)
        return "0";
 
    // Return the largest number
    return num;
}
 
// Driver Code
int main()
{
    string N = "12345";
    string S = "23";
 
    cout << greatestReducedNumber(N, S);
 
    return 0;
}


Java
// Java program to implement
// the above approach
 
import java.io.*;
import java.util.Arrays;
 
class GFG {
 
    // Function to obtain the largest number not exceeding
    // num which does not contain any digits present in S
    static String greatestReducedNumber(String num,
                                        String s)
    {
        // Stores digits of S
        Boolean[] vis_s = new Boolean[10];
        Arrays.fill(vis_s, Boolean.FALSE);
 
        // Traverse the string S
        for (int i = 0; i < (int)s.length(); i++) {
 
            // Set occurrence as true
            vis_s[(int)(s.charAt(i)) - 48] = true;
        }
 
        int n = num.length();
        int in = -1;
 
        // Traverse the string n
        for (int i = 0; i < n; i++) {
            if (vis_s[(int)num.charAt(i) - '0']) {
                in = i;
                break;
            }
        }
 
        // All digits of num are not
        // present in string s
        if (in == -1) {
            return num;
        }
 
    for (char dig = num.charAt(in); dig >= '0'; dig--) {
        if (vis_s[(int)dig - '0'] == false) {
            num = num.substring(0, in) + dig
                  + num.substring(in + 1, n);
            break;
        }
    }
 
    char LargestDig = '0';
 
    for (char dig = '9'; dig >= '0'; dig--) {
        if (vis_s[dig - '0'] == false) {
 
            // Largest Digit not present
            // in the string s
            LargestDig = dig;
            break;
        }
    }
 
    // Set all digits from positions
    // in + 1 to n - 1 as LargestDig
    for (int i = in + 1; i < n; i++) {
        num = num.substring(0, i) + LargestDig;
    }
 
    // Counting leading zeroes
    int Count = 0;
    for (int i = 0; i < n; i++) {
        if (num.charAt(i) == '0')
            Count++;
        else
            break;
    }
 
    // Removing leading zeroes
    num = num.substring(Count, n);
 
    // If the string becomes null
    if ((int)num.length() == 0)
        return "0";
 
    // Return the largest number
    return num;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String N = "12345";
        String S = "23";
 
        System.out.print(greatestReducedNumber(N, S));
    }
}
 
// This code is contributed by subhammahato348


Python3
# Python3 program to implement
# the above approach
 
# Function to obtain the largest number not exceeding
# num which does not contain any digits present in S
def greatestReducedNumber(num, s) :
  
    # Stores digits of S
    vis_s = [False] * 10
     
    # Traverse the string S
    for i in range(len(s)) :
     
      # Set occurrence as true
      vis_s[(ord)(s[i]) - 48] = True   
    n = len(num)
    In = -1
     
    # Traverse the string n
    for i in range(n) :
      if (vis_s[ord(num[i]) - ord('0')]) :
        In = i
        break
     
    # All digits of num are not
    # present in string s
    if (In == -1) :
      return num   
    for dig in range(ord(num[In]), ord('0') - 1, -1) :
      if (vis_s[dig - ord('0')] == False) :
        num = num[0 : In] + chr(dig) + num[In + 1 : n - In - 1]
        break   
    LargestDig = '0'
    for dig in range(ord('9'), ord('0') - 1, -1) :
      if (vis_s[dig - ord('0')] == False) :
     
        # Largest Digit not present
        # in the string s
        LargestDig = dig
        break
     
    # Set all digits from positions
    # in + 1 to n - 1 as LargestDig
    for i in range(In + 1, n) :
      num = num[0 : i] + chr(LargestDig)
     
    # Counting leading zeroes
    Count = 0
    for i in range(n) :
      if (num[i] == '0') :
        Count += 1
      else :
        break
     
    # Removing leading zeroes
    num = num[Count : n]
     
    # If the string becomes null
    if (int(len(num)) == 0) :
      return "0"
     
    # Return the largest number
    return num
     
    # Driver code
N = "12345"
S = "23"
 
print(greatestReducedNumber(N, S))
 
# This code is contributed by divyeshrabadiya07.


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;  
class GFG
{
 
  // Function to obtain the largest number not exceeding
  // num which does not contain any digits present in S
  static string greatestReducedNumber(string num, string s)
  {
     
    // Stores digits of S
    bool[] vis_s = new bool[10];
 
    // Traverse the string S
    for (int i = 0; i < (int)s.Length; i++) {
 
      // Set occurrence as true
      vis_s[(int)(s[i]) - 48] = true;
    }
 
    int n = num.Length;
    int In = -1;
 
    // Traverse the string n
    for (int i = 0; i < n; i++) {
      if (vis_s[(int)num[i] - '0']) {
        In = i;
        break;
      }
    }
 
    // All digits of num are not
    // present in string s
    if (In == -1) {
      return num;
    }
 
    for (char dig = num[In]; dig >= '0'; dig--) {
      if (vis_s[(int)dig - '0'] == false) {
        num = num.Substring(0, In) + dig + num.Substring(In + 1, n - In - 1);
        break;
      }
    }
 
    char LargestDig = '0';
 
    for (char dig = '9'; dig >= '0'; dig--) {
      if (vis_s[dig - '0'] == false) {
 
        // Largest Digit not present
        // in the string s
        LargestDig = dig;
        break;
      }
    }
 
    // Set all digits from positions
    // in + 1 to n - 1 as LargestDig
    for (int i = In + 1; i < n; i++) {
      num = num.Substring(0, i) + LargestDig;
    }
 
    // Counting leading zeroes
    int Count = 0;
    for (int i = 0; i < n; i++) {
      if (num[i] == '0')
        Count++;
      else
        break;
    }
 
    // Removing leading zeroes
    num = num.Substring(Count, n);
 
    // If the string becomes null
    if ((int)num.Length == 0)
      return "0";
 
    // Return the largest number
    return num;
  }
 
  // Driver code
  static void Main() {
    string N = "12345";
    string S = "23";
 
    Console.Write(greatestReducedNumber(N, S));
  }
}
 
// This code is contibuted by divyesh072019


Javascript


输出:
11999

时间复杂度: O(|N| + |s|)
辅助空间: O(1)