1. 概述

在这个教程中,我们将探讨不同的算法,帮助我们在删除一个数字中的k个数字后找到可能的最大数

首先,我们会解释问题。然后,我们会介绍两种不同的算法来满足我们的需求。最后,我们会讨论它们的时间复杂度和空间复杂度。

2. 问题解释

首先,让我们解释算法的目标。我们的目标是在删除数字中的k个数字后找到可能的最大数。

例如,考虑数字286281。我们需要删除的元素数量是2,因此最大的可能数字将是8681。假设我们考虑另一个值k,即2,预期输出将是88。

3. 使用算术

在这一节,我们将看到逻辑解释以及时间复杂度和空间复杂度。

3.1. 逻辑

让我们通过一些算术来了解实现目标的逻辑。我们将使用findLargestNumberUsingArithmetic(num, k)方法来实现我们的逻辑,它返回结果数字。

函数findLargestNumberUsingArithmetic(n,k)接受两个参数:n(原始数字)和k(要删除的数字数量):

public static int findLargestNumberUsingArithmetic(int num, int k) {
    //...
    return num;
}

外部循环迭代k次,代表要删除的数字数量:

for (int j = 0; j < k; j++) {
    //...
}

对于每次迭代,它进入一个内部循环,依次移除每个数字。内部循环计算每次移除一个数字后的数字,并与当前最大数字进行比较:

while (num / i > 0) {
    int temp = (num / (i * 10)) * i + (num % i);
    i *= 10;

    result = Math.max(result, temp);
}
num = result;

移除数字后,如果发现更大的数字,它会更新最大数。

经过k次迭代后,它返回剩余的数字,表示在删除k个数字后可能的最大数字:

3.2. 时间和空间复杂度

外部循环遍历k次。在外部循环内,有一个while循环遍历num的每一位。这个循环对于num的每一位大约执行log10 N次,因为我们每次都将num除以10。因此,内部循环的时间复杂度为O(K*log**10N)。

我们没有使用额外的空间,所以空间复杂度为O(1)。

4. 使用栈

在这一节,我们将看到一种更优化的方法来改进复杂性。

3.1. 逻辑

这种方法涉及使用栈来跟踪数字,同时确保得到的结果最大化。

我们将使用findLargestNumberUsingStack(num, k)方法来实现我们的逻辑,它返回结果数字。

函数findLargestNumberUsingStack(num,k)接受两个参数:num(原始数字)和k(要删除的数字数量)。

首先将数字num转换为字符数组或字符串以便遍历其位:

String numStr = Integer.toString(num); 
int length = numStr.length();

如果要删除的数字数量等于输入数字的长度,我们必须返回0:

if (k == length) return 0;

否则,初始化一个空栈来存储数字:

Stack<Character> stack = new Stack<>();

现在,遍历数字num的每一位并遵循以下步骤:

  • 当栈不为空,当前数字大于栈顶元素,并且剩余要删除的数字(K)大于0时,从栈中弹出元素
  • 将当前数字压入栈中
for (int i = 0; i < length; i++) {
    char digit = numStr.charAt(i);
    while (k > 0 && !stack.isEmpty() && stack.peek() < digit) {
        stack.pop();
        k--;
    }
    stack.push(digit);
}

如果有剩余要删除的数字(K),从栈中弹出元素以满足条件:

while (k > 0) {
    stack.pop();
    k--;
}

最后,根据栈中剩余的数字构建最大数,并返回结果:

while (!stack.isEmpty()) {
    result.insert(0, stack.pop());
}
return Integer.parseInt(result.toString());

4.2. 时间和空间复杂度

算法遍历数字的每一位一次,循环内操作是常数时间的。因此,时间复杂度为O(N)。

所需空间主要取决于用于存储数字位的栈。因此,空间复杂度为O(N)。

5. 总结

在这篇文章中,我们研究了在删除数字中的k个数字后找到可能最大数的算法。我们了解了如何通过算术和栈两种方式实现。我们还讨论了这两种算法的时间和空间复杂度,使我们能够根据需要明智地选择其中之一。

如往常一样,本文中展示的完整代码示例可在GitHub上找到。