- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
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)