Go程序员面试分类模拟题28.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Go程序员面试分类模拟题28是关于如何在短时间内找到百度访问次数最多的IP的一种问题为了解决这个问题,我们可以使用一种称为哈希函数的算法我们将使用`hashIP1024`来进行这种计算首先,我们需要了解一些基本的知识点哈希函数是一种将任意长度的二进制值映射成固定长度的十进制值的函数`1024`是10的10次方,代表210`1234`是12的10次方,代表212当我们将所有连续的2的幂相加得到2121时,得到`21212

Go程序员面试分类模拟题28

论述题

1.?题目描述:

??现有海量日志数据保存在一个超级大的文件中,该文件无法直接读入内存,要求从中提取某天访问百度次数最多的那个IP。

正确答案:

由于这道题只关心(江南博哥)某一天访问百度最多的IP,因此可以首先对文件进行一次遍历,把这一天访问百度的IP的相关信息记录到一个单独的文件中。接下来可以用上一节介绍的方法来求解。由于求解思路是一样的,这里就不再详细介绍了。唯一需要确定的是把一个大文件分为几个小文件比较合适。以IPv4为例,由于一个IP地址占用32位,因此最多会有232=4G种取值情况。如果使用hash(IP)%1024,那么把海量IP日志分别存储到1024个小文件中。这样,每个小文件最多包含4MB个IP地址。如果使用2048个小文件,那么每个文件会最多包含2MB个IP地址。因此,对于这类题目而言,首先需要确定可用内存的大小,然后确定数据的大小。由这两个参数就可以确定hash函数应该怎么设置才能保证每个文件的大小都不超过内存的大小,从而可以保证每个小的文件都能被一次性加载到内存中。

[考点]如何找出访问百度最多的IP

?

2.?题目描述:

??把一个含有N个元素的数组循环右移k(k是正数)位,要求时间复杂度为O(n),且只允许使用两个附加变量。

正确答案:

由于有空间复杂度的要求,因此,只能在原数组中就地进行右移。

??方法一:蛮力法

??蛮力法也是最简单的方法,题目中需要将数组元素循环右移k位,只需要每次将数组中的元素右移一位,循环k次即可。例如,假设原数组为abcd1234,那么,按照此种方式,具体移动过程如下:abcd1234→4abcd123→34abcd12→234abcd1→1234abcd。

??此种方法也很容易写出代码。示例代码如下:

??packagemain??

??import(

??fmt

??)

??funcrightShiftl(arr[]int,kint){

??ifarr==nil{

??fmt.Println(参数不合法)

??return

??}

??ll:=len(arr)

??fork!=0{

??k--

??tmp:=arr[ll-1]

??fori:=ll-1;i>0;i--{

??arr[i]=arr[i-1]

??}

??art[0]=tmp

??}

??}

??funcmain(){

??arr:=[]int{1,2,3,4,5,6,7,8}

??rightShift1(arr,4)

??fmt.Println(方法1)

??for_,v:=rangearr{?

??fmt.Print(v,)

??}

??}

??程序的运行结果为

??56781234

??以上方法虽然可以实现数组的循环右移,但是由于每移动一次,其时间复杂度就为O(n),所以,移动k次,其总的时间复杂度为O(k*n),0<k<n,与题目要求的O(n)不符合,需要继续往下探索。

??对于上述代码,需要考虑到,k不一定小于n,有可能等于n,也有可能大于n。当k>n时,右移k-n之后的数组序列跟右移k位的结果一样,所以,当k>n时,右移k位与右移k(其中k=k%n)位等价,根据以上分析,相对完备的代码如下:

??funcrightShift2(arr[]int,kint){

??ifarr==nil{

??fmt.Println(参数不合法)

??return

??}

??ll:=len(arr)??

??k%=ll

??fork!=0{

??k--

??t:=arr[ll-1]

??fori:=ll-1;i>0;i--{

??arr[i]=arr[i-1]

??}

??arr[0]=t

??}

??}

??算法性能分析:

??上例中,算法的时间复杂度为O(n2),与k值无关,但时间复杂度仍然太高,是否还有其他更好的方法呢?

??仔细分析上面的方法,不难发现,上述方法的移动采取的是一步一步移动的方式,可是问题是,题目中已经告知了需要移动的位数为k,为什么不能一步到位呢?

??方法二:空间换时间法

??通常情况下,以空间换时间往往能够降低时间复杂度,本题也不例外。

??首先定义一个辅助数组T,把数组A的第n-k+1到N位数组中的元素存储到辅助数组T中,然后再把数组A中的第1到n-k位数组元素存储到辅助数组T中,然后将数组T中的元素复制回数组A,这样就完成了数组的循环右移,此时的时间复杂度为O(n)。

??虽然时间复杂度满足要求,但是空间复杂度却提高了,由于需要创建

文档评论(0)

江南博哥 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档