Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对于使用python的CODE和MaxCounters,有可能比O(N+M)更好吗?_Python - Fatal编程技术网

对于使用python的CODE和MaxCounters,有可能比O(N+M)更好吗?

对于使用python的CODE和MaxCounters,有可能比O(N+M)更好吗?,python,Python,这是我在Codibility课程中使用的代码: 每个测试都通过,但最后一个测试all max_计数器操作在7秒后超时,因此结果仅为88%,时间复杂度为ON+M 是否有可能提高算法的时间复杂度,并使用Python获得100%的测试结果 MaxCounters任务 为您提供了N个计数器,最初设置为0,您可以对它们执行两种可能的操作: 递增− 计数器X增加1, 最大计数器− 所有计数器都设置为任何计数器的最大值。 给出了一个由M个整数组成的非空数组。此数组表示连续的操作: 如果A[K]=X,则1≤ X

这是我在Codibility课程中使用的代码:

每个测试都通过,但最后一个测试all max_计数器操作在7秒后超时,因此结果仅为88%,时间复杂度为ON+M

是否有可能提高算法的时间复杂度,并使用Python获得100%的测试结果

MaxCounters任务 为您提供了N个计数器,最初设置为0,您可以对它们执行两种可能的操作:

递增− 计数器X增加1, 最大计数器− 所有计数器都设置为任何计数器的最大值。 给出了一个由M个整数组成的非空数组。此数组表示连续的操作:

如果A[K]=X,则1≤ X≤ N、 那么操作K是递增x, 如果[K]=N+1,则操作K是最大计数器。 为以下假设编写有效的算法:

N和M是[1..100000]范围内的整数; 数组A的每个元素都是[1..N+1]范围内的整数。 编辑:根据此答案评论中的讨论,跟踪最后一次操作以避免在连续的max_计数器操作中不必要地重置阵列是实现此目标的关键。以下是不同的解决方案—一个跟踪最大值,另一个计算按需最大值—在实现该更改时的效果:

def solution(N, A):
    counters = [0] * N
    max_c = 0
    last_was_max = False
    for el in A:
        if el <= N:
            counters[el - 1] += 1
            max_c = max(counters[el - 1], max_c)
            last_was_max = False
        elif not last_was_max:
            counters = [max_c] * N
            last_was_max = True
    return counters


def solution2_1(N, A):
    counters = [0] * N
    last_was_max = False
    for el in A:
        if el <= N:
            counters[el - 1] += 1
            last_was_max = False
        elif not last_was_max:
            counters = [max(counters)] * N
            last_was_max = True
    return counters
编辑:根据此答案评论中的讨论,跟踪最后一次操作以避免在连续的max_计数器操作中不必要地重置阵列是实现此目标的关键。以下是不同的解决方案—一个跟踪最大值,另一个计算按需最大值—在实现该更改时的效果:

def solution(N, A):
    counters = [0] * N
    max_c = 0
    last_was_max = False
    for el in A:
        if el <= N:
            counters[el - 1] += 1
            max_c = max(counters[el - 1], max_c)
            last_was_max = False
        elif not last_was_max:
            counters = [max_c] * N
            last_was_max = True
    return counters


def solution2_1(N, A):
    counters = [0] * N
    last_was_max = False
    for el in A:
        if el <= N:
            counters[el - 1] += 1
            last_was_max = False
        elif not last_was_max:
            counters = [max(counters)] * N
            last_was_max = True
    return counters

这里有一个100%的解决方案:

# MaxCounters
def solution(N, A):
    count = [0] * N
    max_count = 0
    last_max = False
    for val in A:
        if val == N + 1 and last_max == False:
            count = [max_count] * N
            last_max = True
            continue
        if val <= N:
            count[val - 1] += 1
            max_count = max(count[val - 1], max_count)
            last_max = False
    return count


这里有一个100%的解决方案:

# MaxCounters
def solution(N, A):
    count = [0] * N
    max_count = 0
    last_max = False
    for val in A:
        if val == N + 1 and last_max == False:
            count = [max_count] * N
            last_max = True
            continue
        if val <= N:
            count[val - 1] += 1
            max_count = max(count[val - 1], max_count)
            last_max = False
    return count

我不懂Python。 但是我的kotlin解决方案在极端测试中运行得更快,因为更多的MaxCounter。

▶特大型

所有max_计数器操作✔嗯

0.280秒可以 0.264秒没问题 我相信这个测试是为了避免在max过程中对阵列进行完全更新。 如果你可以避免,你应该能够得到100%。 因此,无论使用哪种语言,请尽最大努力停止完整的数组更新

我在第一次尝试时得到了88%,我用了一个小时得到了这个原始的新答案。在一次最大值操作后,所有计数器都有相同的值,因此在最后一次最大值操作之前,检查每个计数器的意义不大。我在找到最后一个Max操作后创建了数组,因此根本不需要数组完全更新

我不懂Python。 但是我的kotlin解决方案在极端测试中运行得更快,因为更多的MaxCounter。

▶特大型

所有max_计数器操作✔嗯

0.280秒可以 0.264秒没问题 我相信这个测试是为了避免在max过程中对阵列进行完全更新。 如果你可以避免,你应该能够得到100%。 因此,无论使用哪种语言,请尽最大努力停止完整的数组更新


我在第一次尝试时得到了88%,我用了一个小时得到了这个原始的新答案。在一次最大值操作后,所有计数器都有相同的值,因此在最后一次最大值操作之前,检查每个计数器的意义不大。我在找到最后一个Max操作后创建了阵列,因此根本不需要阵列完全更新

请确保您的问题是独立的。我们不知道MaxCounters从Codibility中学到了什么,即使Codibility停业,这个问题仍然有意义。补充链接可以,但回答问题所需的一切都应该尽可能在问题内部。您是否尝试过不在每次递增计数器时计算最大值,而在需要时只计算总最大值?一些想法:首先,在elif el>N,您应该实际比较问题指定的elif el==N+1。第二,idk如果[max_c]*N是否分配了一个新数组,那就值得检查:如果分配了,您应该编写自己的for循环来更改现有数组的元素,而不是分配一个新数组。最后,对O表示法的一点意见是:尽可能低的表示法很重要,但其中隐藏的常数在现实中也同样重要。请确保您的问题是独立的。我们不知道MaxCounters从Codibility中学到了什么,即使Codibility停业,这个问题仍然有意义。补充链接可以,但回答问题所需的一切都应该尽可能在问题内部。您是否尝试过不在每次递增计数器时计算最大值,而在需要时只计算总最大值?一些想法:首先,在elif el>N,您应该实际比较问题指定的elif el==N+1。其次,idk如果[max_c]*N是否分配了一个新数组,那么值得检查一下:如果分配了,您应该编写自己的for循环来更改现有数组i的元素
而不是分配一个新的。最后,对O表示法的一点意见是:尽可能低的表示法很重要,但其中隐藏的常数在现实中也同样重要。感谢您指出如何优化if条件。这可以通过练习中的假设来实现。您的解决方案实际上具有ON*M的时间复杂度,即使它对您的测试用例的性能更好,因为很少计算最大值。N的预期值为50000,这意味着平均而言,在a中,每50001个元素只执行一次最大运算。我敢肯定,对于这个用例,您可以将理论计算抛到窗外,因为最大运算的机会与所述运算的成本成反比-计数器的数量越高,最大运算的成本越高,但同时,实际发生一次的概率越低。事实上,最大运算发生的概率为1/N+1,复杂度为N。假设计数器增量可以在恒定时间内完成,我的算法的复杂度应为M*[N/N+1*1+1/N+1*N]=M*[N+1/N+1]=M,其中,N/N+1是增量发生的概率乘以恒定时间成本1,1/N+1是最大值发生的概率乘以实际成本。你是对的,我也更喜欢maxcounters解决方案。它也更具可读性。这实际上是我首先向Codibility提交的解决方案,但在最后三次测试中失败,超时导致分数仅为40%。我对最大操作数较高的情况进行了更多的思考——您可能会通过消除连续的最大操作来骗过一些改进,因为它们不会改变输出和性能因此,允许跳过该步骤。这可以通过跟踪最后一个op是否是带有布尔变量的max来实现,并且仅在需要时重置数组来指出如何优化if条件。这可以通过练习中的假设来实现。您的解决方案实际上具有ON*M的时间复杂度,即使它对您的测试用例的性能更好,因为很少计算最大值。N的预期值为50000,这意味着平均而言,在a中,每50001个元素只执行一次最大运算。我敢肯定,对于这个用例,您可以将理论计算抛到窗外,因为最大运算的机会与所述运算的成本成反比-计数器的数量越高,最大运算的成本越高,但同时,实际发生一次的概率越低。事实上,最大运算发生的概率为1/N+1,复杂度为N。假设计数器增量可以在恒定时间内完成,我的算法的复杂度应为M*[N/N+1*1+1/N+1*N]=M*[N+1/N+1]=M,其中,N/N+1是增量发生的概率乘以恒定时间成本1,1/N+1是最大值发生的概率乘以实际成本。你是对的,我也更喜欢maxcounters解决方案。它也更具可读性。这实际上是我首先向Codibility提交的解决方案,但在最后三次测试中失败,超时导致分数仅为40%。我对最大操作数较高的情况进行了更多的思考——您可能会通过消除连续的最大操作来骗过一些改进,因为它们不会改变输出和性能因此,允许跳过该步骤。这可以通过跟踪上一个op是否是带有布尔变量的max来实现,并且只有在需要时才重置数组if语句的最轻微反转会将结果降低到66%!!我很惊讶。用一段时间来代替for循环,当最后一个测试用例达到最大超时时,我达到了88%。那些if语句稍微反转一下,结果就会下降到66%!!我很惊讶。使用while代替for循环,当最后一个测试用例达到最大超时时,我实现了88%。
# MaxCounters
def solution(N, A):
    count = [0] * N
    max_count = 0
    last_max = False
    for val in A:
        if val == N + 1 and last_max == False:
            count = [max_count] * N
            last_max = True
            continue
        if val <= N:
            count[val - 1] += 1
            max_count = max(count[val - 1], max_count)
            last_max = False
    return count

    # MaxCounters
def solution(N, A):
    max_counter = 0
    list_counters = [0]*N
    if N < min(A):
        return list_counters
    for i in A:
        if i <= N:
            list_counters[i-1] += 1
            max_counter = max(list_counters[i-1], max_counter)
        else:
            list_counters = [max_counter]*N
    return list_counters