我刚刚学习了数据结构,谁能告诉我为什么哈希很慢,谢谢!
此问题来自LeetCode: https://leetcode.com/problems/happy-number/
bool isHappy(int n) {
unordered_map<int, int> M;
M[0] = 0, M[1] = 1, M[2] = 4, M[3] = 9, M[4] = 16, M[5] = 25,\
M[6] = 36, M[7] = 49, M[8] = 64, M[9] = 81;
int temp, mark = 0; //temp is next n, mark is for detect circle
while(n){
temp = 0;
if(n == 1) return true;
if(n < 10){
if(mark == n)
return false;
mark = n;
}
//calc next n
while(n){
temp += (n%10)*(n%10); // 4 ms
//temp += M[n%10]; // 8 ms
n /= 10;
}
n = temp;
}
}
答案 0 :(得分:3)
为什么不呢?散列是有效的,因为它的平均获取时间不变。就是这样。
无法保证它比*
更快。请注意,您的密钥通常是 NOT 直接用作哈希表的密钥(这称为&#34; 直接地址表&#34;它有自己的密钥缺点)。通常,您的密钥计算为哈希密钥:hash_key = hash(your_key)
。所以时间完全取决于hash
的实施方式。一旦计算了散列键,它只是索引表的问题。
事实上,散列的最常见实现涉及模数(%)操作,该操作最可能慢于&#39; *&#39;。试想一下:C = A % B
相当于C = A – B * (A / B)
。
您可能会问两个%
(如*
案例)与一个%
(如地图案例中)有何关系?我的猜测是n%10
被优化为在第一种情况下只计算一次。
答案 1 :(得分:1)
这并没有回答你的问题,但在这种情况下使用std::unordered_map
是对内存和CPU周期的过度浪费。一个简单的数组在这里也可以正常工作,几乎肯定会更快。
bool isHappy(int n) {
static const int M[] = { 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 };
int temp, mark = 0; //temp is next n, mark is for detect circle
while(n){
temp = 0;
if(n == 1) return true;
if(n < 10){
if(mark == n)
return false;
mark = n;
}
//calc next n
while(n){
temp += M[n%10];
n /= 10;
}
n = temp;
}
}