1.原理

把一些复杂的数据,通过某种函数映射关系,映射成更加易于查找的方式。每个数据都会映射为独一无二的地址,数据存储时,它会存储于这个地址,取数据时,还会在这个地址取。哈希算法就像一本字典,当需要查词的时候,通过目录找到页码,再到对应页码就能找到所需要的内容了。

这种映射关系有可能会发生多个关键字映射到同一地址的现象,称为冲突。在这种特殊情况下,需要对关键字进行第二次或更多次的处理,在其他的大多数情况下,哈希算法可以实现在常数时间内存储和查找这些关键字。

2.应用

2.1.两个数的和

(1)问题描述

在给定的一些数字中找出两个数,使得它们的和为N,前提是这些数据中保证有答案,并且只有一个答案。

输入:nums=[3, 4, 5, 7, 10],target=11

输出:1,3

(2)实现

def two_sums(nums, target):
    mydict = {}
    for i in range(len(nums)):
        m = nums[i]
        if target-m in mydict:
            return i, mydict[target-m]
        else:
            mydict[m] = i


nums = [3, 4, 5, 7, 10]
target1 = 11
print(two_sums(nums, target1))

2.2.团体赛问题

(1)问题描述

团体赛的比赛项目有男子单打、女子单打、男子双打、女子双打。

规定,同一类别的比赛项目如果出现多次,则参赛人员必须一致;同一个或一组人员不能参与多个项目。

判断派出的选手是否合规。

(2)实现

如果赛事出场顺序和出场选手只存在一对一的对应关系,不存在一对多和多对多的对应关系,就可以说明两个字符串匹配成功。

对于本题来说,我们建立模式字符串中每个字符和目标字符串中每个单词之间的映射关系,而哈希表本身就是一种映射关系,因此可以使用哈希算法来存储这种关系。

第一项任务是建立哈希表来存储数据,由于不仅需要排除一个模式对应多个字符串的情况,还需要排除多个模式对应一个字符串的情况,我们需要建立两个哈希表:mydict和used。

def test(games, players):
    mydict = {}
    used = {}
    if len(games) != len(players):
        return False

    for i in range(len(games)):
        game = games[i]
        if game in mydict:
            if players[i] != mydict[game]:
                return False

        else:
            mydict[game] = players[i]
            if players[i] in used:
                return False
            else:
                used[players[i]] = True
    return True


games1 = ["男单", "女双", "女双", "男单"]
players1 = ["李四", "张/王组合", "张/王组合", "李四"]

games2 = ["男单", "女双", "女双", "男单"]
players2 = ["李四", "张/王组合", "李四", "张/王组合"]

games3 = ["男单", "女双", "女单", "男单"]
players3 = ["李四", "张/王组合", "李四", "李四"]

print(test(games1, players1))
print(test(games2, players2))
print(test(games3, players3))

2.3.