从一组范围

时间:2017-09-08 03:30:57

标签: python algorithm

我是Python和SWE的新手,所以请原谅简单的问题。面试官给了我以下编码挑战。我提出了以下解决方案。但我被通过了,因为它没有达到他们的表现标准。我想知道是否有人可以指点我如何在这个问题上做得更好,一般来说这样的问题。我已经找到了解决问题的其他答案,但我想要实现具体的答案。

以下是我收到的反馈意见:

  1. while(zip_range_list):行突出:你不会看到很多 在Python中使用循环,你不必在括号内加上括号 测试表达式,用while循环解决这个问题是一个 奇怪的事情要做。 为什么while循环是一个坏主意?
  2. 在reduce_zip_ranges减少之前添加范围,然后 不断引用刚刚添加的元素 reduced_zip_ranges [-1]而不是单独的绑定 读得很尴尬。 为什么这很尴尬?
  3. 构造范围range_check = range(low-1,high + 2)可能是正确的,但它看起来既奇怪又浪费空间浪费:他不是比较端点而是构建整个范围的列表数字只是为了检查 该范围内的会员资格。他一遍又一遍地建造这些 循环内循环。 我明白了这一点。我试图避免一个 如果声明很长。不是个好主意。
  4. 说到循环中的"循环",这是一个O(N平方)算法,当它在排序后可能是O(N)时。 我想我忽略了这一点,我现在看到0(n ^ 2)。我该如何避免这种情况?
  5. 该例程有两个不同的非特殊回报点;循环中的那个是不必要的(代码也可以用它注释掉)。
  6. 问题 给定一组邮政编码范围(每个范围包括两者 他们的上限和下限), 提供一种算法,产生所需的最小范围数 表示与输入相同的覆盖范围。

    Input: [[14,17], [4,7], [2,5], [10,12] , [15,16], [4,9], [11,13]]
    Output: [[2,17]]
    
    
    # Implementation
    def zip_range_reducer(zip_range_list):
    
        if not zip_range_list:
            raise Exception("Empty list of ranges provided!")
    
        reduced_zip_ranges = []
    
        zip_range_list.sort()
    
        while (zip_range_list):
            no_overlap_ranges = []
            reduced_zip_ranges.append(zip_range_list[0])
            if len(zip_range_list) == 1:
                return reduced_zip_ranges
            zip_range_list.pop(0)
            for zip_range in zip_range_list:
                low, high = reduced_zip_ranges[-1][0], reduced_zip_ranges[-1][1]
                range_check = range(low-1, high+2)
                if zip_range[0] in range_check or zip_range[1] in range_check:
                    reduced_zip_ranges[-1][0] = min(reduced_zip_ranges[-1][0], zip_range[0])
                    reduced_zip_ranges[-1][1] = max(reduced_zip_ranges[-1][1], zip_range[1])
                else:
                    no_overlap_ranges.append(zip_range)
            zip_range_list = no_overlap_ranges
    
        return reduced_zip_ranges
    

    另外

1 个答案:

答案 0 :(得分:0)

这是O(n)解决方案。 [不包括排序的复杂性]

def reduceRangeList(ranges):
    # sorting the list based on the lower limit, and then based on size as tie breaker
    # note we need the bigger ranges to come before the smaller ranges
    ranges.sort(key= lambda pair : (pair[0], - pair[1]))

    reduced= []     # new set of ranges are stored here

    # we use a parent range to decide if a range is inside other ranges
    parent= ranges[0]

    # this will for sure be part of the solution,
    # because it is the largest, leftmost range
    reduced.append(ranges[0])

    for x in ranges:
        if parent[0] <= x[0] and x[1] <= parent[1]:
            # this range is completely within another range, ignore!
            continue
        elif x[0] <= parent[1]:
            # this range is partially inside the parent range
            # so we set the parent to cover this two range
            parent= [parent[0], x[1]]
        else:
            #this range is completely outside the parent range
            parent= x

        # If the range is completely or partially outside other ranges...
        # I'm placing it here to avoid duplicate code
        reduced.append(x)

    return reduced




def main():
    ranges= [[1,5], [2, 4], [6, 7], [2,7], [9,10]]
    # ranges= [[1,5], [1,4], [2, 6]]
    # ranges= [[1,2], [3,4], [5,6], [1,6], [6,7], [4, 8]]


    reduced= reduceRangeList(ranges)

    print(reduced)

if __name__ == '__main__':
    main()
相关问题