三月你好!
庭院深深深几许,杨柳堆烟,帘幕无重数。玉勒雕鞍游冶处,楼高不见章台路。雨横风狂三月暮,门掩黄昏,无计留春住。泪眼问花花不语,乱红飞过秋千去。——欧阳修《蝶恋花·庭院深深深几许》
给定两个非负整数 x x x 和 y y y,如果某一整数等于 x i + y j x^i + y^j xi+yj,其中整数 i > = 0 i >= 0 i>=0 且 j > = 0 j >= 0 j>=0,那么我们认为该整数是一个强整数。
返回值小于或等于 bound 的所有强整数组成的列表。
你可以按任何顺序返回答案。在你的回答中,每个值最多出现一次。
提示: 1 <= x <= 100
1 <= y <= 100
0 <= bound <= 10^6
示例 :
输入:x = 2, y = 3, bound = 10
输出:[2,3,4,5,7,9,10]
解释:
2 = 2^0 + 3^0
3 = 2^1 + 3^0
4 = 2^0 + 3^1
5 = 2^1 + 3^1
7 = 2^2 + 3^1
9 = 2^3 + 3^0
10 = 2^0 + 3^2
通过分析,本题采用暴力破解,只要找出 i i i、 j j j的可取值范围,并对 i i i、 j j j进行遍历,就可以找出不大于bound的所有强整数,但是在保存结果时需要对当前结果进行查找,保证不重复,为了减小查找的代价,可额外使用哈希表处理。 下面对 i i i、 j j j的边界进行分析: 如果 x = 1 且 y = 1 , x=1且y=1, x=1且y=1,则输出结果为2;当 x = 2 x=2 x=2, x i < x i + y j ≤ 1 0 6 x^i<x^i+y^j\le10^6 xi<xi+yj≤106 , 2 20 = 2 10 ∗ 2 10 = 1024 ∗ 1024 > 1 0 6 2^{20}=2^{10}*2^{10}=1024*1024>10^6 220=210∗210=1024∗1024>106,所以 i i i边界最大可取20,同理 j j j的边界也可取20,如果 x 、 y x、y x、y的值更大,则 i i i、 j j j的边界值应更小,同样满足要求。程序暴力求解的代价其实也不大。
class Solution {
public:
vector powerfulIntegers(int x, int y, int bound) {
vector temp;
unordered_map hashmap;
int i,j;
for(i=0;i<20;++i){
for(j=0;j<20;++j){
int v = pow(x,i) + pow(y,j);
if((pow(x,i) + pow(y,j))<=bound )
if(!hashmap[v]){ //哈希表用于判断当前结果中不存在v
temp.push_back(v);
hashmap[v]++;
}
}
}
return temp;
}
};
看似简单的题目我硬是提交了几十次,leetcode网站莫不是有BUG。
哈希表(Hash Table)又叫散列表,是一种便于程序查找的数据结构,下面我按照自己的理解对哈希表做一个简单的介绍。
比如在C++中有这样一个数组V:
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
数值 | 265 | 24 | 74 | 16 | 128 | 25 | 37 | 43 |
现在的任务是:想在数组中查找一个数值,如果存在就返回索引。一般的如果数组长度不大,或者查找任务不复杂,直接对数组进行遍历就可以了。但是如果数组规模十分庞大,比如成百万上千万的话,那查找一个数的时间代价就很大了。最理想的查找情况是,你给我一个数,我简单运算就知道这个数应该存放在哪,直接去对应的地址找索引,那就再好不过了。哈希表就是这样的数据结构。针对上述数组V构建下面长度为11哈希表H,构建方法如下:
比如索引0对应的数值是265,265除以11等于24余1,于是把索引0存放在余数的位置,也就是哈希地址为1 处。同理,其他数值的索引依次存放。
这里除数取余的方法被称为哈希函数 f ( ) f() f(),这是一种比较简单的哈希函数,被除数一般是素数,数值265被称为键值 k e y key key。
哈希地址 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
记录 (索引) | 0 | 1 | 5 | 6 | 3 | 4 | 2 | 7 | |||
记录对应的数值 | 265 | 24 | 25 | 37 | 16 | 128 | 74 | 43 |
哈希表构造好了以后,想查找一个数比如128,求 f ( 128 ) f(128) f(128)知道存放在哈希地址7处,在数组中对应的索引是4;查找 f ( 119 ) f(119) f(119)分析哈希地址9处为空,表示数组中不存在119这个数。
你应该注意到根据哈希函数构造哈希表时,有可能不同的键值得到的哈希地址相同,需要存放在同一处,这称之为哈希冲突。应尽可能避免哈希冲突,如扩大哈希表空间或使用不同的哈希函数以及其他的优化策略。哈希表不只可以处理数字,也可以处理文字等其他的数据类型,只不过哈希函数可能需要自行构造。
简单来说,哈希表是一种用空间换时间的方法,有它的优势比如便于查找,也有他的缺点比如插入或删除数据困难。