Advent of Code deste ano的第六天有一个有趣的问题,可以讨论算法的优化并使用数据结构。
第6天的问题
第6天"problema de sintonização"的问题是找到一个没有重复元素的后续性。我建议尝试先解决它。
简单解决方案
解决代码出现中问题的一种简单方法是找到没有大并发症的简单解决方案。对于这个问题,基于总力的解决方案在于测试所有可能的后续性,它满足了这一要求。可以通过解决问题的输入,提取后续性并验证如果在这种情况下所有元素进行验证来实现,这是最后一个可以使用一组集合(对dia 3的问题进行评论)进行完成(评论)是否验证其是否验证大小是©©©与次序列相等,因为集合“删除”重复元素。示例:
from itertools import count
tamanho = 4
for i in count():
subsequencia = entrada[i:i + tamanho]
if len(set(entrada[i:i + tamanho])) == tamanho:
# resposta encontrada
第一个问题 - 性能
解决方案在传播所有输入时,解决方案的作品,对于输入的每个位置时,它需要执行另一个等于所需后续性(O(n * tamanho)
)大小的操作。这可以使此算法越慢,因此您想要更高的后续性。
理想将是一种仅取决于输入大小的算法(O(n)
),因此我们需要开发任何机制来保持哪些字符在后续中,请检查新字符是否阅读或不读o并丢弃从读取这个新角色的持续时间(O(1)
)中读出的角色。如果我们想保持这种角色上次出现的立场,那么如果他在里面或不在后来寻找角色阅读的大小和位置的情况下,就可以回答他。当我们保持最后一个重复性的位置是幻想时,确定没有重复的读取了多少个字符,因此当您达到所需的尺寸时,找到答案。将这些想法汇总在一起,我们有以下算法:
tamanho = 4
posicao_das_letras = {}
ultima_duplicidade = -1
for i, c in enumerate(entrada):
if posicao_das_letras.get(c, -1) > ultima_duplicidade:
ultima_duplicidade = posicao_das_letras.get(c, -1)
else:
if i - ultima_duplicidade == tamanho:
# resposta encontrada
posicao_das_letras[c] = i
O(1)
),我们在线性天气中产生算法(O(n)
)。
第二个问题 - 数据结构
移植表表可能会出现哈希碰撞问题,因此具有相对复杂的实现。与此问题一样,有一组相对受限制的键,256个字符考虑1个字节中的所有可能值(或26个字符,仅考虑a
的字母©z
),并且可以轻松解释这些值由于no。©可以使用列表位置作为密钥使用简单列表代替字典。示例:
tamanho = 4
posicao_das_letras = [-1 for _ in range(256)]
ultima_duplicidade = -1
for i, c in enumerate(ord(c) for c in entrada):
if posicao_das_letras[c] > ultima_duplicidade:
ultima_duplicidade = posicao_das_letras[c]
else:
if i - ultima_duplicidade == tamanho:
# resposta encontrada
posicao_das_letras[c] = i
这样,使用了更简单的数据结构,并获得了相同的结果。这种方法还将在哈希碰撞方面存在问题,并且其计算时间没有问题,因为它不使用哈希功能,而使该算法不太容易受到问题的影响。
我观察到的另一个挑战是在2376 da beecrowd可能使用更简单的数据结构的情况下,这归结为为冠军建立钥匙,最后说获胜者。因为它具有类似于单个单独的视觉结构,而是通过观察游戏的顺序来实现它来解决它的第一个冲动,所以可以使用一条行解决此问题,这可能更重要的是实施由于不必担心河流的深度正在进行。
考虑
并非每个问题都可以在线性时间内解决,当它的时间时,您可能需要更多地研究问题并搜索最佳数据结构。