📜  算法测验| SP2竞赛1 |问题7(1)

📅  最后修改于: 2023-12-03 15:41:09.805000             🧑  作者: Mango

算法测验 | SP2竞赛1 | 问题7

本题为SP2竞赛1的第7题,要求实现一个功能为从一个数组中找出不重复的最长子串的算法。

数据输入

输入格式为一个数组,例如:

arr = [1, 2, 3, 2, 1, 4, 5, 6, 7, 8, 9]
数据输出

输出格式为两个整数,分别为不重复最长子串的开始位置和长度,例如:

start = 5, length = 5

表示最长的不重复子串为[4, 5, 6, 7, 8],开始位置为5,长度为5。

解决方案

本题可以使用双指针来解决,具体思路如下:

  1. 定义左指针与右指针,初始值均为0
  2. 定义一个哈希表用于存储元素出现次数
  3. 遍历数组,每次将当前元素加入哈希表,若当前元素重复,则移动左指针到重复元素的下一位,直到不重复为止
  4. 若当前子串长度大于历史最大长度,则更新最大长度,并记录开始位置
  5. 重复步骤3和4,直到遍历完整个数组

时间复杂度为O(n),空间复杂度为O(n)。

以下为Python代码实现:

def find_longest_non_dup_substring(arr):
    start = 0
    max_len = 0
    char_dict = {}

    left = 0
    right = 0

    while right < len(arr):
        # 判断当前元素是否出现过
        if arr[right] in char_dict and char_dict.get(arr[right]) >= left:
            left = char_dict[arr[right]] + 1
        else:
            char_dict[arr[right]] = right

        right += 1

        # 判断当前子串长度是否大于历史最大长度
        if right - left > max_len:
            max_len = right - left
            start = left

    return start, max_len
使用说明

使用时传入一个数组作为参数即可,例如:

arr = [1, 2, 3, 2, 1, 4, 5, 6, 7, 8, 9]
start, length = find_longest_non_dup_substring(arr)
print(f"start = {start}, length = {length}")

输出为:

start = 5, length = 5
总结

本题是一个经典的双指针题目,在算法面试中比较常见,需要掌握此类题型的解决方法。