我的leetcode之旅--强整数与哈希表

三月你好!
庭院深深深几许,杨柳堆烟,帘幕无重数。玉勒雕鞍游冶处,楼高不见章台路。雨横风狂三月暮,门掩黄昏,无计留春住。泪眼问花花不语,乱红飞过秋千去。——欧阳修《蝶恋花·庭院深深深几许》
我的leetcode之旅--强整数与哈希表_第1张图片

强整数(2019.02.28)

题目描述

给定两个非负整数 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=1y=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+yj106 , 2 20 = 2 10 ∗ 2 10 = 1024 ∗ 1024 > 1 0 6 2^{20}=2^{10}*2^{10}=1024*1024>10^6 220=210210=10241024>106,所以 i i i边界最大可取20,同理 j j j的边界也可取20,如果 x 、 y x、y xy的值更大,则 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之旅--强整数与哈希表_第2张图片

一句话总结

看似简单的题目我硬是提交了几十次,leetcode网站莫不是有BUG。
我的leetcode之旅--强整数与哈希表_第3张图片

哈希表简介

哈希表(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这个数。
你应该注意到根据哈希函数构造哈希表时,有可能不同的键值得到的哈希地址相同,需要存放在同一处,这称之为哈希冲突。应尽可能避免哈希冲突,如扩大哈希表空间或使用不同的哈希函数以及其他的优化策略。哈希表不只可以处理数字,也可以处理文字等其他的数据类型,只不过哈希函数可能需要自行构造。
简单来说,哈希表是一种用空间换时间的方法,有它的优势比如便于查找,也有他的缺点比如插入或删除数据困难。

你可能感兴趣的:(我的leetcode之旅--强整数与哈希表)