如果我们观察以下情况,我们可以找到 O(n) 解决方案:
- 如果
(i, j) 是pi - xi 最大且pj + xj 最大的索引,那么(i, j) 就是pi + pj + |xj - xi| 最大的索引
证明:由于pi + pj + |xj - xi|等于(pi - xi) + (pj + xj)或(pj - xj) + (pi + xi),当我们交换i和j时,(pj - xj) + (pi + xi)变为(pi - xi) + (pj + xj),最大pi + pj + |xj - xi| 的值小于或等于(pi - xi) + (pj + xj) 的最大值。所以现在只要证明(pi - xi) + (pj + xj) 等于pi + pj + |xj - xi| 就足够了,(pi - xi) 是最大值,(pj + xj) 是最大值,因此(pi - xi) + (pj + xj) 是最大值。如果pi - xi 是最大值,pj + xj 是最大值,则(pi - xi) + (pj + xj) 是最大值。还有xj - xi >= 0 持有。 (否则,如果 xj - xi < 0、(pi - xi) + (pj + xj) < (pj - xj) + (pi + xi) 和 pi - xi < pj - xj 或 pj + xj < pi + xi 与 pi - xi 和 pj + xj 是最大值相矛盾。)因此,(pi - xi) + (pj + xj) = pi + pj + |xj - xi| 和 (i, j) 是最大化它的索引。
因此,为了最大化pi + pj + |xj - xi|,我们只需要找到分别最大化pi - xi 和pj + xj 的索引(i, j)。
这是微不足道的
- 可以在 O(n) 中找到最大化
pi - xi 的索引 i
- 可以在 O(n) 中找到最大化
pj + xj 的索引 j
因此,作为答案的索引(i, j) 可以在 O(n) + O(n) = O(n) 中找到。
用python编写的完整解决方案如下。 (您似乎还假设i != j,因为否则示例答案将是(2, 2),而不是(2, 3)。因此添加了一些代码以确保添加了i != j。)
# Time complexity: O(n) where n is len(t_p) or len(t_x)
def get_argmax(t_p, t_x, operator, excluded_index=None):
max = -float('inf')
argmax = None
for i, (p, x) in enumerate(zip(t_p, t_x)):
if i == excluded_index:
continue
if operator(p, x) > max:
max = operator(p, x)
argmax = i
return argmax
# get the answer indices (i, j)
# which maximizes t_p[i] + t_p[j] + |t_x[j] - t_x[i]|
# in time complexity O(n) where n is len(t_x) or len(t_p)
def get_answer(t_x, t_p):
argmax_i = get_argmax(t_p, t_x, lambda a, b: a - b) # O(n)
argmax_j = get_argmax(t_p, t_x, lambda a, b: a + b) # O(n)
answer = (argmax_i, argmax_j)
# The if statement below is for to make sure that argmax_i != argmax_j
if argmax_i == argmax_j:
second_argmax_i = get_argmax(t_p, t_x,
lambda a, b: a - b, argmax_i) # O(n)
second_argmax_j = get_argmax(t_p, t_x,
lambda a, b: a + b, argmax_j) # O(n)
max1 = (t_p[argmax_i] - t_x[argmax_i]) + (t_p[second_argmax_j] +
t_x[second_argmax_j])
max2 = (t_p[second_argmax_i] - t_x[second_argmax_i]) + (t_p[argmax_j] +
t_x[argmax_j])
if max1 >= max2:
answer = (argmax_i, second_argmax_j)
else:
answer = (second_argmax_i, argmax_j)
return answer
if __name__ == '__main__':
t_x = [5, 3, 12]
t_p = [10, 20, 5]
answer = get_answer(t_x, t_p)
answer_one_based_index = (answer[0] + 1, answer[1] + 1)
print(f'The answer is {answer_one_based_index}.')
打印出来:
The answer is (2, 3).