【问题标题】:Minimum steps needed to make all elements equal by adding adjacent elements通过添加相邻元素使所有元素相等所需的最小步骤
【发布时间】:2021-05-24 08:38:40
【问题描述】:

我有一个大小为 N 的数组 A。所有元素都是正整数。在一个步骤中,我可以添加两个相邻元素并用它们的总和替换它们。也就是说,数组大小减少了 1。现在我需要通过执行最少的步骤使所有元素相同。

例如:A = [1,2,3,2,1,3]。

第 1 步:合并索引 0 和 1 ==> A = [3,3,2,1,3]

第 2 步:合并索引 2 和 3(新数组的)==> [3,3,3,3]

因此步数为 2。

我想不出一个直接的解决方案,所以尝试了一种递归方法,通过一个一个地合并所有索引并返回当数组大小为 1 或所有元素相等时我可以获得的最小级别。

下面是我试过的代码:

# Checks if all the elements are same or not
def check(A):
    if len(set(A)) == 1:
        return True
    return False

# Recursive function to find min steps
def min_steps(N,A,level):
    # If all are equal return the level
    if N == 1 or check(A):
        return level
    
    # Initialize min variable
    mn = float('+inf')
    # Try merging all one by one and recur
    for i in range(N-1):
        temp = A[:]
        temp[i]+=temp[i+1]
        temp.pop(i+1)
        mn = min(mn, min_steps(N-1,temp, level+1))
    return mn

此解决方案的复杂度为 O(N^N)。我想将它减少到接近 O(N^2) 或 O(N^3) 的多项式时间。谁能帮我修改这个解决方案或告诉我是否遗漏了什么?

【问题讨论】:

  • 所有元素都是严格正数吗?
  • @user202729 是的,他们都是积极的。
  • 和积分? ...
  • @user202729 所有元素都是正整数。 N的值最高可达1000。
  • @ggorlen 是的,我们可以进行多次合并。并且最多可以有 N-1 次合并,因为在该数组之后将剩下 1 个元素满足条件。

标签: arrays python-3.x recursion dynamic-programming backtracking


【解决方案1】:

组合任何 k 个相邻的元素对(即使它们包括由之前的组合步骤形成的元素)总共会留下 nk 个元素,我们可以将每个元素映射回构成元素的原始问题的连续子数组加在一起形成它。所以,这个问题等价于将数组划分为尽可能多的连续子数组,使得所有子数组的和都相同:同一子数组中的任何相邻元素对都可以组合成一个元素,并且这个过程在以任意顺序选择相邻对的子数组,直到所有元素组合成一个元素。

所以,如果有 n 个元素并且它们总和为 T,那么一个简单的 O(nT) 算法是:

  1. 对于从 0 到 T 的 i:
    • 尝试将元素划分为子数组,每个子数组的和为 i。 这相当于沿数组扫描,如果当前子数组中的元素之和严格

一个小的加速是只尝试将 T 整除的目标 i 值。

编辑: 为了将时间复杂度从 O(nT) 提高到 O(n^2),只需尝试与数组前缀总和相对应的目标 i 值(因为必须是一个包含第一个元素的子数组,并且这个子数组只能有这样的和)。

【讨论】:

  • 谢谢!!我理解你的做法。这意味着它与DP或回溯无关。
猜你喜欢
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多