如果你能将一双袜子的单个配对抽象为键本身和其它配对作为值,我们就可以利用哈希。
在地板上为你和你的配偶各划出一个虚拟区域。
从一堆袜子中取出一只。
现在按照以下规则逐个将袜子放在地板上:
重复步骤3,直到所有袜子都用完。
解释:
哈希和抽象
抽象是一个非常强大的概念,已经被用于改善用户体验(UX)。与计算机的实际交互中抽象的例子包括:
- 文件夹图标用于GUI(图形用户界面)中的导航,以访问地址而不是键入实际地址以导航到位置。
- GUI滑块用于控制各种音量级别、文档滚动位置等。
哈希或其他非就地解决方案不是选项,因为我无法复制我的袜子(尽管如果我能这样做,那将是很好的)。
我认为提问者考虑应用哈希,使得在放置它们之前应该知道任何一双袜子所属的插槽。
这就是为什么我建议将放置在地板上的单只袜子本身抽象为哈希键(因此无需复制袜子)。
如何定义我们的哈希键?
如果有多个相似的袜子,下面的键定义也适用。也就是说,假设有两对黑色男士袜子PairA和PairB,每只袜子都被命名为PairA-L、PairA-R、PairB-L、PairB-R。因此,PairA-L可以与PairB-R配对,但PairA-L和PairB-L不能配对。
假设任何袜子都可以通过以下方式唯一标识:
Attribute[Gender] + Attribute[Colour] + Attribute[Material] + Attribute[Type1] + Attribute[Type2] + Attribute[Left_or_Right]
这是我们的第一个哈希函数。让我们使用一个简短的符号表示为h1(G_C_M_T1_T2_LR)
。h1(x)不是我们的位置键。
另一个消除左右属性的哈希函数将是h2(G_C_M_T1_T2)
。这第二个函数h2(x)是我们的位置键!(用于你身后地板上的空间)。
- 要定位插槽,请使用h2(G_C_M_T1_T2)。
- 一旦找到插槽,然后使用h1(x)检查它们的哈希值。如果它们不匹配,则您有一对。否则,将袜子扔进同一个插槽。
注意:由于我们在找到一对后会移除它,因此可以安全地假设最多只有一个具有唯一h2(x)或h1(x)值的插槽。
如果每只袜子都恰好有一双匹配的袜子,那么使用h2(x)来查找位置,如果没有成对的袜子,则需要检查,因为可以安全地假设它们是一双袜子。
在地板上放置袜子的重要性
让我们考虑一种情况,即把袜子堆叠在一起形成一堆(最坏情况)。这意味着我们别无选择,只能进行线性搜索以找到一双袜子。
将它们散落在地板上可提供更多的可见性,从而提高发现匹配袜子(与哈希密钥匹配)的机会。当一只袜子在第3步放在地板上时,我们的大脑下意识地记住了它的位置。
- 因此,在我们的记忆中如果存储了该位置,我们就可以直接找到匹配的一对袜子。
- 如果位置没有被记住,不用担心,我们仍然可以返回到线性搜索。
从地板上拿走匹配的一对袜子的重要性
- 短期人类记忆在要记住的项目较少时效果最好。因此,增加我们使用哈希来发现一对袜子的概率。
- 这也将减少在线性搜索袜子时需要搜索的项目数量。
分析
- 情况1:当Derpina无法直接使用哈希技术去记住或找到地板上的袜子时,进行线性搜索。这不比遍历堆来寻找一对更糟。
- 比较的上限:O(n^2)。
- 比较的下限:(n/2)。 (当每另一只袜子Derpina拾起是前一只的一对时)。
- 情况2:Derp记得他放在地板上每只袜子的位置,并且每只袜子都恰好有一对。
- 比较的上限:O(n/2)。
- 比较的下限:O(n/2)。
我所说的比较操作,从堆中取出袜子必然需要n次操作。因此,实际的下限将是n次迭代和n/2次比较。
加快速度
为了达到完美的分数,使得Derp能够进行O(n/2)次比较,我建议Derpina:
- 花更多的时间与袜子相处以熟悉它。是的,这意味着也要花更多的时间与Derp的袜子在一起。
- 玩像在网格中找对子这样的记忆游戏可以提高短期记忆表现,这可能非常有益。
这是否等同于元素唯一性问题?
我建议的方法是解决元素唯一性问题的方法之一,其中将它们放入哈希表并进行比较。
考虑到您的特殊情况只存在一个确切的配对,因此它已经非常等同于元素唯一性问题。因为我们甚至可以对袜子进行排序并检查相邻的袜子是否匹配(EDP的另一种解决方案)。
但是,如果给定袜子可能存在多个配对,则与EDP偏离。
waitpid
函数,这样作为父进程,你甚至不需要亲自整理任何袜子? - Mxyk