试图用二进制搜索解决python问题

时间:2019-05-29 17:22:13

标签: python python-3.x

enter image description here嘿,我正在尝试解决这个python练习问题,但是我的解决方案不在给定的时间限制内,有人可以解释一下。这将对您非常有帮助,因为在任何地方我都找不到这个问题的python解决方案,他们在Java中给出了与我几乎相同的解决方案

https://www.hackerearth.com/practice/algorithms/searching/binary-search/practice-problems/algorithm/victory-over-power-4a0cb459/description/

tasks_count = int(input())

tasks = []

def binarysearch(x):
    arr = tasks
    if arr == [] or x > arr[0]: return 0
    elif x < arr[-1]: return len(arr)
    l  = 0
    r = len(arr)
    while l <= r: 
        mid = int((l + r) / 2);
        if arr[mid] == x: 
            return mid 
        elif arr[mid] > x: 
            l = mid - 1
        else: 
            r = mid + 1
    return mid


for i in range(0, tasks_count):
    n = input().split(' ')
    if n[0] == '1':
        pos = binarysearch(int(n[1]))
        tasks.insert(pos, int(n[1]))
    elif len(tasks) < 3:
        print('Not enough enemies')
    else:
        print(tasks[(int(len(tasks)/3))])

解决方案2:

tasks_count = int(input())

tasks = []

for i in range(0, tasks_count):
    n = input().split(' ')
    if n[0] == '1':
        tasks.append(int(n[1]))
    elif len(tasks) < 3:
        print('Not enough enemies')
    else:
        tasks.sort(reverse=True)
        print(tasks[int(len(tasks)/3)-1])

1 个答案:

答案 0 :(得分:0)

解决方案#2主要是目标,但是有一些问题会不必要地减慢它的速度。一方面,input函数比直接从sys.stdin读取要慢得多;根据我的简短实验,循环range和调用input的时间比循环islice的{​​{1}}的时间长10倍。

它还会执行一些复杂的计算,将索引转换为sys.stdin再返回到float,这可以避免:

int

可以直接计算为:

int(len(tasks)/3)-1

使用len(tasks) // 3 - 1 下位除法运算符直接计算//

一个较小的改进是用int分隔行,这样您就不必处理手动索引编制了(这可能会很慢,而且读起来不那么明显)。

最后的优化是将您的工作捆绑在一个函数调用中; CPython变量在全局范围内存储和加载需要str.partition操作,而在局部范围内,它们是运行速度更快的简单C数组查找。

在所有这些因素中,您最终得到的代码更像:

dict

如果他们有意强制执行频繁的排序,这可能仍然太慢(因为Python的TimSort尝试有效地处理大多数排序的输入,相对于简单的索引和附加,它仍然需要大量工作)。可能需要使用import sys from itertools import islice def main(): tasks_count = int(next(sys.stdin)) tasks = [] for line in islice(sys.stdin, tasks_count): task_type, sep, task_value = line.partition(' ') if task_type == '1': tasks.append(int(task_value)) elif len(tasks) < 3: print('Not enough enemies') else: tasks.sort(reverse=True) print(tasks[len(tasks) // 3 - 1]) if __name__ == '__main__': # Standard import guard main() # Call main 模块(该模块为您实现二进制搜索,但在运行速度更快的扩展模块中)保持排序不变,在这种情况下,您删除了{{1} }进行完全调用,以使其在插入时保持有序(将每个任务#2的bisect工作替换为每个任务#1的sort工作)。方便地,由于Python允许使用负索引,因此您不必按降序对其进行排序,因此同样可以轻松地(如果不太容易)沿向上方向计算所需索引:

O(n log n)