找到最大的三的倍数

17 Mar 2025 | 6 分钟阅读

问题陈述

我们得到一个数字数组,我们的任务是找出通过按任何顺序连接这些数字中的部分或全部数字可以创建的最大的三的倍数。如果无法形成有效的三的倍数,则返回空字符串。为了处理潜在的大小问题,结果应以字符串形式返回,避免不必要的前导零。

Java 实现

Java 方法 1

输出

Finding the Largest Multiple of Three

代码解释

  • 该 Java 代码实现了一种算法,用于从数字数组中找到最大的三的倍数。核心思想是维护一个字符串数组 dp,表示每个模 3 余数的最大三的倍数。
  • 该算法迭代数字数组,相应地更新 dp 数组。它考虑了三种情况:当前数字可被 3 整除,当前数字加上余数形成三的倍数,或者当前数字有助于形成一个新的最大三的倍数。
  • len 数组跟踪每个余数的最大倍数的长度。然后通过连接 dp[0] 字符串,并删除任何前导零来获得结果。该算法利用动态规划有效地处理了构建最大三的倍数的不同场景。

时间复杂度

  • 导致时间复杂度的主要因素是使用 Arrays.sort() 在开头对数字数组执行的排序操作。排序操作的时间复杂度为 O(N log N),其中 N 是输入数组的长度。

空间复杂度

  • 空间复杂度是常数,因为无论输入大小如何,使用的额外空间都保持不变。所采用的主要数据结构(例如数组和字符串)不随输入大小而扩展。

缺点

  • 所提供解决方案的缺点是它依赖于排序,这导致时间复杂度为 O(N log N)。对于某些情况,特别是当数字数组已经排序或接近排序时,这种排序操作可能被认为是过度的。
  • 在这种情况下,通过利用输入的固有顺序,可以提高算法的效率。此外,该算法使用带有数组的动态规划,这可能会增加更大输入的空间使用量,从而影响其可扩展性。

Java 方法 2

输出

Finding the Largest Multiple of Three

代码解释

  • 该 Java 代码旨在从数字数组中找到最大的三的倍数。它获取用户输入,解析逗号分隔的数字,然后调用 largestMultipleOfThree 方法计算结果。封装在 largestMultipleOfThree 方法中的算法采用动态规划方法。
  • 它迭代数字数组,更新每个模 3 余数的最大三的倍数。结果通过连接动态规划数组的元素获得。

时间复杂度

  • 该算法的时间复杂度为 O(N+M),其中 N 是输入数组中数字的个数;M 是唯一数字的个数。在算法的第一次迭代中,执行数字频率计数,而在第二次迭代中构造结果。

空间复杂度

  • 空间复杂度为 O(M),其中 M 是唯一数字的个数。该算法使用一个数组(计数器)来存储每个数字的频率,并且无论输入大小如何,该数组的大小都是常数(10 个元素)。

缺点

  • 该解决方案的缺点是它使用贪婪方法来调整数字以形成最大的三的倍数。虽然这种方法在许多情况下有效,但它可能无法保证全局最优。在某些情况下,在一步中做出局部最优选择可能会导致次优的整体解决方案。
  • 在所有情况下,可能需要更详尽的搜索或动态规划方法才能获得全局最优解。

Java 方法 3

输出

Finding the Largest Multiple of Three

时间复杂度

  • 该算法的时间复杂度取决于旨在找到最小数字并将其删除的循环的迭代次数。
  • 最坏的情况是需要多个周期才能将总和转换为三的倍数。对于此问题,
  • 执行时间量级约为 O(N),其中 N 表示给定输入数组中的数字个数。

空间复杂度

  • 空间复杂度为 O(1),因为无论输入大小如何,使用的额外空间都是常数。数组 mod1、mod2 和 count 具有固定大小(每个 10 个整数),并且 StringBuilder ans 随输入中数字的个数线性增长。