📜  门| Gate IT 2007 |问题24(1)

📅  最后修改于: 2023-12-03 14:58:23.713000             🧑  作者: Mango

门| Gate IT 2007 |问题24

问题描述:

有一个长度为n的整数数组,找到两个不同的下标i和j,使得ai=aj且|i-j|最大。

输入格式:

第一行包含一个整数n,表示数组长度。

第二行包含n个整数,表示该数组。

输出格式:

一个整数,表示满足条件的最大|i-j|。

样例输入1:

5 4 6 2 6 7

样例输出1:

3

样例输入2:

6 7 1 7 1 7 1

样例输出2:

5

提示:

数据范围:2≤𝑛≤4096,数组中每个数的绝对值不超过10^6。

算法1:

这道题可以使用哈希表来解决。对于数组中的每一个数,我们记录下它最后出现的位置,然后计算每一对相同数之间的距离,最后返回距离的最大值即可。需要注意的是,因为数组中可能存在负数,所以对于每一个数,我们需要额外记录下它最后出现的位置,以及它第一次出现的位置。

时间复杂度:O(n)

以下是python的代码实现:

def max_distance(n, nums):
    # 记录每个数最后出现的位置和第一次出现的位置
    last = {}
    first = {}
    for i, num in enumerate(nums):
        if num in last:
            last[num] = i
        else:
            last[num] = i
            first[num] = i
    # 计算每一对相同数之间的距离,并返回距离的最大值
    res = 0
    for num in first:
        res = max(res, last[num] - first[num])
    return res

n = int(input())
nums = list(map(int, input().split()))
print(max_distance(n, nums))

算法2:

这道题还可以使用二分查找来解决。对于数组中的每一个数,我们二分查找其第一次出现的位置和最后一次出现的位置,然后计算距离,最后返回距离的最大值即可。

时间复杂度:O(nlogn)

以下是python的代码实现:

def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left + right) // 2
        if arr[mid][0] < target:
            left = mid + 1
        elif arr[mid][0] > target:
            right = mid - 1
        else:
            return mid
    return -1

def max_distance(n, nums):
    # 记录每个数第一次出现的位置和最后一次出现的位置
    first = []
    last = []
    for i, num in enumerate(nums):
        if binary_search(first, num) == -1:
            first.append((num, i))
        last.append((num, i))
    # 计算每一对相同数之间的距离,并返回距离的最大值
    res = 0
    for num, first_index in first:
        last_index = binary_search(last, num)
        res = max(res, last[last_index][1] - first[first_index][1])
    return res

n = int(input())
nums = list(map(int, input().split()))
print(max_distance(n, nums))

以上两种算法无论哪种方法都方便记忆和编写,时间复杂度也都很优秀,代码比较简单。