【问题标题】:Count number of element in a array that is less than the element in another array计算数组中小于另一个数组中元素的元素数
【发布时间】:2018-10-14 11:41:39
【问题描述】:

我不确定这是否是提出这个问题的正确地方,但我自己也在努力寻找正确的答案。我已经进行了编程测试,但我无法弄清楚为什么我的代码在某些测试用例中会失败。

问题是给定一个未排序的元素数组,例如 [1, 4, 2, 4] 和一个最大值数组,例如 [3,5],给出第一个数组中元素计数的解小于第二个数组中的最大值。即 [2, 4]

举个例子

输入

nums = [2, 10, 5, 4, 8]
maxes = [3, 1, 7, 8]

输出

solution = [1, 0, 3, 4]

输入

nums = [1, 4, 2, 4]
maxes = [3, 5]

输出

solution = [2, 4]

因为有一个元素是小于或等于3,0元素是小于或等于1和3元素是小于或等于3和4元素是小于或等于8

【问题讨论】:

  • 为什么不包括 1 它的计数小于最大数组中的项目,似乎与 2 没有什么不同
  • 第一个solution不应该是[1, 0, 3, 3]吗?

标签: python arrays sorting


【解决方案1】:

伪代码:

Sort number array
Sort maximum array
create a list counts
for max elem in max array
      find first elem in number array that is greater than or 
      equal to max elem and save its (index+1) in counts

所以现在 counts 将是一个与已排序数字数组平行的数组。在计数的索引 0 处,我们的元素数量小于 max 数组的索引 0 处的数量。

如果您需要字典形式的数据(就像您在解决方案中所做的那样)而不是两个并行列表,您可以执行以下操作。

Set index to 0
for max elem in max array:
    dictionary[max elem] = counts[index]
    index += 1

请注意,您可以在上面使用 enumerate,但我不确定您是否知道它,所以我尝试提供最简单的解决方案。

【讨论】:

    【解决方案2】:

    这是您需要做的简化版本

    nums = [1, 4, 2, 4]
    maxes = [3,5]
    
    result = [0]*len(maxes)
    for index, max_val in enumerate(maxes):
        for num in nums:
            if num <= max_val:
                result[index] += 1
    
    print(result)
    

    【讨论】:

    • 从算法上来说,与接受的答案相比,它根本不是很有效
    【解决方案3】:

    我只是把它写成

    [sum(1 for x in nums if x < m) for m in maxes]
    

    演示:

    >>> nums = [2, 10, 5, 4, 8]
    >>> maxes = [3, 1, 7, 8]
    >>> 
    >>> [sum(1 for x in nums if x < m) for m in maxes]
    [1, 0, 3, 3]
    >>>    
    >>> nums = [1, 4, 2, 4]
    >>> maxes = [3, 5]
    >>> 
    >>> [sum(1 for x in nums if x < m) for m in maxes]
    [2, 4]
    

    它可读性强、内存效率高、使用用 C 实现的快速理解,您必须努力找到一个可以证明进一步微优化是合理的示例。

    【讨论】:

    • 从算法上来说,与接受的答案相比,它根本不是很有效
    • @Tomchan 我鼓励您为实现计时。必须考虑排序的开销、传统的for 循环和__setitem__ 调用。此外,在公认的解决方案中,“在数字数组中找到第一个元素...”是在外部 for 循环体内进行线性扫描,因此也具有二次复杂度。
    • 在接受的答案中,它对数组进行了排序。因此,如果您考虑解决方案的工作原理,它基本上是说,我有一个从排序数字数组开始的计数器,我检查 max 的第一个元素,如果它小于或等于,否则您增加 max 上的计数器大批。所以你实际上浏览了一次列表
    • 而您的答案是,它会再次扫描整个数组以查找最大列表中的每个最大值,而不管先前的工作是否完成,因为您没有对数组进行排序。因此,您的实现效率并不高,从算法上讲它是次要的。这意味着,如果我可以投入时间和精力,我可以提出比您更好的实现。
    【解决方案4】:
    def find_total_matches(team_a, team_b):
        if not team_b:
            return []
        if not team_a:
            return [0]*len(team_b)
        team_a.sort()
        team_b_sorted = sorted(team_b)
        a_i = 0
        b_i = 0
        c_sum = 0
        cnt = dict()
        while a_i <len(team_a) and b_i < len(team_b_sorted):
            val= team_b_sorted [b_i]
            if val not in cnt:
                while a_i < len(team_a) and val >= team_a[a_i]:
                    c_sum += 1
                    a_i += 1
                cnt[val] = c_sum
            b_i += 1
        result = []
        for val in team_b:
            result.append(cnt[val])
    
        return result
    
    

    【讨论】:

      猜你喜欢
      • 2019-06-14
      • 2019-06-05
      • 2018-01-27
      • 1970-01-01
      • 2016-07-19
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多