需要有关此问题的帮助。 This is the problem
我们说,如果| x,则两个整数x和y的差值至少为K。 -y | ≥K(其差的绝对值至少为K)。给定 N个整数a1,a2,...,aN和K的序列,总变化计数 是序列中元素对的数量,其变化为 最小K,即它是对对的大小
{(i,j)|1≤i<j≤N and|ai−aj|≥K}
例如,如果K = 1且序列为3,2,4,则答案为3。如果K = 1,顺序为3、1、3,则答案为2。
您的任务是编写一个程序,该程序采用序列和值K 作为输入并计算总变异数。
输入格式
第一行包含两个正整数N和K,中间用a分隔 空间。
其后是包含N个由空格分隔的整数的行 给出序列的值。
输出格式
单行中的单个整数给出了总变化计数。
测试数据
您可以假设输入中的所有整数都在0到 10 ^ 8(含)。
Subtask 1 (40 marks) : 1 ≤ N ≤ 4000, 1 ≤ K ≤ 10^8 Subtask 2 (60 marks) : 1 ≤ N ≤ 65000, 1 ≤ K ≤ 10^8
我为此使用了O(n)
解决方案,但仍然无法通过高级测试用例。您能否指出一些测试用例的执行时间很长,更重要的是如何解决这个问题。
n,k=map(int,input().split())
li=list(map(int,input().split()))
count=0
li.sort()
i=0
j=1
while(i<n and j<n):
if(abs(li[i]-li[j])>=k):
count+=(n-j)
i+=1
j=i+1
else:
j+=1
print(count)
答案 0 :(得分:0)
您的解决方案肯定是否 O(n)
,因为您使用的是list.sort()
,时间复杂度为O(n log n)
(它使用的是Timsort
内部)。
据我所知,您的方法似乎合理。只是一些改进提示:
elem_i
)来保存num_list[i]
,因此您不需要进行如此多的列表查找。abs()
的调用(元素j
始终大于或等于i
)。这是您的(f1()
)和我的(f2()
)版本的代码;它被编写为函数,因此我可以对其进行基准测试:
def f1(num_list, k):
num_list.sort()
n = len(num_list)
count = 0
i = 0
j = 1
while i < n and j < n:
if abs(num_list[i] - num_list[j]) >= k:
count += (n-j)
i += 1
j = i + 1
else:
j += 1
return count
def f2(num_list, k):
num_list.sort()
n = len(num_list)
count = 0
i = 0
j = i + 1
elem_i = num_list[i]
while i < n and j < n:
if num_list[j] - elem_i >= k:
count += (n - j)
i += 1
j = i + 1
elem_i = num_list[i]
else:
j += 1
return count
以我的代码为基准:
import timeit
import random
for n in [1000, 4000, 10000]:
numbers = [random.randint(0, 10**8) for _ in range(n)]
for k in [10**1, 10**3, 10**5, 10**7]:
t1 = timeit.timeit(
'f(numbers, k)', 'from __main__ import numbers, k, f1 as f',
number=10)
t2 = timeit.timeit(
'f(numbers, k)', 'from __main__ import numbers, k, f2 as f',
number=10)
print('n {:10,d} | k {:10,d} | {:10.4f} | {:10.4f} | best f{}'.format(
n, k, t1, t2, '1' if t1 < t2 else '2'))
assert f1(numbers, k) == f2(numbers, k)
这些结果给了我
n 1,000 | k 10 | 0.0026 | 0.0020 | best f2
n 1,000 | k 1,000 | 0.0026 | 0.0020 | best f2
n 1,000 | k 100,000 | 0.0044 | 0.0033 | best f2
n 1,000 | k 10,000,000 | 0.1585 | 0.0919 | best f2
n 4,000 | k 10 | 0.0102 | 0.0074 | best f2
n 4,000 | k 1,000 | 0.0097 | 0.0076 | best f2
n 4,000 | k 100,000 | 0.0365 | 0.0243 | best f2
n 4,000 | k 10,000,000 | 2.3722 | 1.3992 | best f2
n 10,000 | k 10 | 0.0255 | 0.0190 | best f2
n 10,000 | k 1,000 | 0.0260 | 0.0194 | best f2
n 10,000 | k 100,000 | 0.1938 | 0.1190 | best f2
n 10,000 | k 10,000,000 | 15.2469 | 9.0770 | best f2
这不是很大的进步,但这是有的。不过,我不知道它是否对您有帮助。