从排序数组到排序多项式数组的算法

时间:2017-01-12 09:09:26

标签: python algorithm python-2.7 sorting polynomial-math

处理下面的问题,主要的想法是,(1)如果A> 0,从两端合并,在这种情况下,两端与数组的中间相比具有更大的值,(2)如果A< 0,从两端合并,在这种情况下,两端的数值比数组的中间值小。

想知道是否有任何更聪明的想法可以改善性能(例如时间复杂性或其他观点),空间复杂性改进或我的代码中的任何错误?

问题

给定一个排序的整数数组X和3个整数A,B和C.返回相应的有序多项式数组。

换句话说,对数组中的每个元素x应用A x x + B * x + C并返回已排序的数组。

Python 2.7中的源代码

def f(v, a, b, c):
    return a*v*v + b*v + c

def sort_polynomial(numbers, a, b, c):
    result = []
    if a > 0:
        start = 0
        end = len(numbers) - 1
        while start <= end:
            if f(numbers[start], a, b, c) <= f(numbers[end], a, b, c):
                result.insert(0, (numbers[end], f(numbers[end], a, b, c)))
                end -= 1
            else:
                result.insert(0, (numbers[start], f(numbers[start], a, b, c)))
                start += 1
    elif a < 0:
        start = 0
        end = len(numbers) - 1
        while start <= end:
            if f(numbers[start], a, b, c) <= f(numbers[end], a, b, c):
                result.append((numbers[start], f(numbers[start], a, b, c)))
                start += 1
            else:
                result.append((numbers[end], f(numbers[end], a, b, c)))
                end -= 1
    else:
        raise Exception('invalid argument!')

    return result

if __name__ == "__main__":
    numbers = [-2, -1, 0, 1, 2]
    print sort_polynomial(numbers, 1, 2, 1)
    print sort_polynomial(numbers, -1, 2, 1)

2 个答案:

答案 0 :(得分:2)

你有功能

F(x) = A*x^2 + B * x + C

查找最小值或最大值(x值-B/2A)。如果extrema在您的数据范围内,请获取具有极值的索引,并以合并方式从开头(如果最小)或从结束(如果最大)填充输出数组 - 您已经实现了一种合并。

在这种情况下(初步存储器分配,无插入)复杂度是线性O(N)

答案 1 :(得分:1)

扩展MBo的优秀答案,这是一个可能的实现:

import bisect
import heapq

def f(a, b, c):
    return lambda x: a*x*x + b*x + c

def sort_polynomial(numbers, a, b, c):
    if a == 0:
        return map(f(a, b, c), numbers)              # No x^2 term? Just map!
    apex = -b / ( 2 * a )                            # Find min or max
    middle_index = bisect.bisect_left(numbers, apex) # Where to cut list in half
    numbers = map(f(a, b, c), numbers)               # Apply f
    l1 = numbers[0:middle_index]                     # Part before apex
    l2 = numbers[middle_index:]                      # Part after apex
    if a < 0:
        l2.reverse()                                 # Revert after apex
    else:
        l1.reverse()                                 # Revert before apex
    return list(heapq.merge(l1, l2))                 # Merge and return

if __name__ == "__main__":
    numbers = [-2, -1, 0, 1, 2]
    print sort_polynomial(numbers, 0, 2, 1)
    print sort_polynomial(numbers, 1, 0, 0)
    print sort_polynomial(numbers, 1, 2, 1)
    print sort_polynomial(numbers, -1, 2, 1)