【问题标题】:How to solve Pair sum Problem in python with time complexity of O(nlogn) or O(n)?如何解决时间复杂度为 O(nlogn) 或 O(n) 的 Python 中的对和问题?
【发布时间】:2020-04-09 07:17:16
【问题描述】:

数组中的对和

给定一个随机整数数组 A 和一个数字 x。查找并打印数组中总和为 x 的元素对。 数组 A 可以包含重复的元素。 打印一对时,先打印较小的元素。 也就是说,如果有效对是 (6, 5),则打印“5 6”。没有限制必须在第一行打印 5 对。您可以按任何顺序打印对,只是要注意对中元素的顺序。

输入格式:
第 1 行:整数 N(数组大小)
第 2 行:数组元素(以空格分隔)
第 3 行:整数 x

输出格式:
第 1 行:对 1 个元素(以空格分隔)
第 2 行:对 2 个元素(以空格分隔)
第 3 行:依此类推

约束:
1 1

示例输入:

9
1 3 6 2 5 4 3 2 4
7

样本输出:

(1 6)
(3 4)
(3 4)
(2 5)
(2 5)
(3 4)
(3 4)

我的方法::
1.取2个指针/标记开始和结束
分别指向数组的第一个和最后一个元素:
2. 对数组排序 -o(nlogn)
3.虽然开始 使用开始和结束指针检查总和
如果指针的总和大于实际总和,则将结束指针从 end-1 减小,如果较小,则将起始指针增加到 start+1。

代码:

def pairSum(arr, x):
    arr.sort()  # nlogn
    i = 0
    j = len(arr) - 1

    while i < j:
        if arr[i] + arr[j] > x:
            j -= 1

        elif arr[i] + arr[j] < x:
            i += 1

        else:  # got the match  arr[i] +arr[j] ==x
            if arr[i] <= arr[j]:
                print(arr[i], arr[j])

                if arr[j - 1] == arr[j]:
                    j -= 1

                elif arr[i + 1] == arr[i]:
                    i += 1
                else:
                   i += 1
                   j -= 1

            else:
                print(arr[j], arr[i])
                if arr[i + 1] == arr[i]:
                    i += 1
                elif arr[j - 1] == arr[j]:
                    j -= 1
                else:
                    i += 1
                    j -= 1

我已经尝试过这个问题,它对于唯一元素工作正常,但对于重复元素失败,这是因为 while 循环它提前终止。 请分享您的想法:)

【问题讨论】:

  • 如何分享您的代码以便我们提出改进建议?
  • @Cheerag Verma 嗨,欢迎来到 stackoverflow。像有人问“请帮我做作业……”的问题通常不太受欢迎。在您的情况下,您说您有一个在某些条件下失败的解决方案。请分享此解决方案以及您在重复案例中遇到的错误,我们可能会帮助您找到问题。但是,如果不从头开始,就很难帮助您。另请参阅 stackoverflow.com/help/how-to-ask,了解人们如何最有效地提问。
  • 感谢@Chris 的指导。

标签: python arrays algorithm data-structures


【解决方案1】:

首先: 一旦你对数组进行了排序并且你有了while i &lt; j:,这意味着在第一个else: 中,条件if arr[i] &lt;= arr[j]: 总是正确的,所以我只是简化它。

第二: 你的问题是当你有arr[i + 1] == arr[i]arr[j - 1] == arr[j]。在您的实现中,在这种情况下,您将减少导致一对丢失的 j 值,因此我将为此条件创建一个 if。

可能的修正:

#...
        else:  # got the match  arr[i] +arr[j] ==x
            print(arr[i], arr[j])

            if arr[j - 1] == arr[j] and arr[i + 1] == arr[i]:
                print(arr[i], arr[j])
                print(arr[i], arr[j])
                i += 1
                j -= 1

            elif arr[j - 1] == arr[j]:
                j -= 1

            elif arr[i + 1] == arr[i]:
                i += 1

            else:
                i += 1
                j -= 1

【讨论】:

    【解决方案2】:

    对于 O(n) 复杂度,您可以使用字典来收集与匹配总和相对应的数字(即 target-n),并在您浏览列表时直接访问它:

    numbers = [1, 3, 6, 2, 5, 4, 3, 2, 4]
    target  = 7
    
    matches = dict()
    for n in numbers:
        for m in matches.get(n,[]):
            print(f"{n} {m}" if n<m else f"{m} {n}")
        matches.setdefault(target-n,[]).append(n)
    

    输出:

    1 6
    2 5
    3 4
    3 4
    2 5
    3 4
    3 4
    

    请注意,当列表中有重复项时,实际上不可能完美地达到 O(n),因为要打印的结果数量可能呈指数级 > n

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-04
      • 1970-01-01
      • 1970-01-01
      • 2019-07-10
      • 2015-05-25
      • 2019-12-09
      • 1970-01-01
      相关资源
      最近更新 更多