关于这个问题,经过这么久的讨论,两篇文章及大家的回复,已经比较很清楚了。这里就来完整的整理一下解答。其实本来已经整理得差不多了,不过很不幸,电脑忽然罢工,怎么也启动不了,然后又感冒了,所以一直到现在才开始做这个解答。

好了,不说这个了。下面进入正题。

这个题目来源于某公司的 面试题,是absolute同学在我的“面试题收集贴”中提出的,之后CMGS同学在回复中提到,腾讯今年的面试题中有类似题目,问题规模扩大了10倍,但是本质相同。下面我们来看一下题目:

10亿个正整数,只有其中1个数重复出现过,要在O(n)的时间里面找出这个数,内存要尽可能少(小于100M)。

这个问题,下面有同学提出题目不严谨,我看了一下,的确是和我希望表达的意思有些模糊,我这里将题目从我自己的角度澄清一下:

对于正整数,其范围为1-10亿,然后从中随机的选择出k个数(可以重复,也可以不重复,从具体题目的要求来看),选择完之后开始做题目,无论是对其排序,还是找重复数。

不知道这样表达是不是清楚。

我们首先不急着来解决这个问题,而是从其来源来慢慢看。这里提到的题目与面试题有一些不同(在面试题中是要求找重复的数,而这里的题目是对其进行排序),所以不要感觉疑惑。

[来源]

这种类型的题目,其来源为《编程珠玑》这本书,这里推荐这本书一下,但是由于这本书比较薄,所以里面涉及到的知识只能简单提到,但是并不能够完全覆盖,所以读这本书还是要经历将其读厚的过程,对涉及到的知识点,通过其它参考书来得到关于其的全部知识。另外,尽管这本书的翻译还不错,但是还是推荐下载或得到其英文版进行参考,对于中文版中感觉了解不是很清楚的地方,再来对照英文版 看看。

该题的原型是在《编程珠玑》的开头,题目在“面试题之10亿正整数问题”中我已经详细介绍过了,而且园子中应该大部分兄弟都有这本书吧,我就不详细将书中内容重新打一遍了。

大概介绍一下,作者通过和程序员交谈,了解到程序员需要在一个大系统中实现一个电话号码的文本 数据库,读入电话号码,输出排序好的以800开头的文件。

通过作者的整理,得到精确的问题陈述如下

输入:

所输入的是一个文件,至多包含n个正整数,每个正整数都要小于n,这里的n为10^7。如果输入时某一个整数出现了两次,就会产生一个致命的错误。这些整数与其他任何数据都不关联。

输出:

以增序形式输出经过排序的整数列表。(这里应该补充一下是文件形式吗?)

约束:

至多(大概)只有1MB的可用主存,但是可用磁盘空间非常充足。运行时间至多只允许几分钟,最适宜的时间大概为10秒钟。

[解答]

从上面的这些描述来看一下,题1为10亿正整数的问题,题2为《编程珠玑》中的问题。

题1中问题规模为10亿,也就是10^9,内存要求为小于100M,问题要求是找出重复的数;

题2中问题规模为10^7,而内存要求为1M左右,问题要求是对这些数进行排序。

同时题1中要求算法的时间复杂度为O(n)。

这里我们就来看一下《编程珠玑》中是怎样来解决这个问题的。

《编程珠玑》中使用了三种方法来对其进行解决。一种为Merge Sort,一种为Multi-pass Sort,还有一种为作者起名的Wonder Sort。这里我们会一个个分析一下这些算法,包括时间复杂度和空间复杂度,同时在后面还会有实例的说明。

Merge Sort

Merge Sort大家应该很熟悉,是惯常使用的一种外排序方法,其主要思想是采用了分而治之的思想,该思想被应用于多个算法领域。其中文称为归并排序,在大部分的算法书中都会提到,同时也是外排序中经常使用到的排序方法。

归并排序可以通过迭代和递归两种方式来实现。

这些实现在殷人昆的那本黄书中可以找到(大家应该知道我说的是哪本书吧),但是他的那本书的实现有些不太好,使用了datalist和staticlinklist这两个与归并排序本身无关的数据结构,而这里我们用来示例的话只需要int的数组即可。(另外加上文件读写操作,针对题目的话),所以这里我们仅仅参考一部分黄书中的实现,来自己实现归并排序方法。

归并排序可以使用多种方法来进行实现,这里只谈常规方式下的归并排序,在这种情况下,我们需要和被排序数组同样大小的一个额外空间来辅助进行排序。

 1  #include  < iostream >
 2  using   namespace  std;
 3 
 4  void  merge( int  initlist[],  int  mergedlist[], int  l, int  m,  int  n)
 5  {
 6       int  i = l,j = m + 1 ,k = l;
 7       while (i <= m  &&  j <= n)
 8      {
 9           if (initlist[i] <= initlist[j])
10          {
11              mergedlist[k] = initlist[i];
12              i ++ ;
13              k ++ ;
14          }
15           else
16          {
17              mergedlist[k] = initlist[j];
18              j ++ ;
19              k ++ ;
20          }
21      }
22       if (i <= m)
23      {
24           for ( int  n1 = k,n2 = i;n1 <= n && n2 <= m;n1 ++ ,n2 ++ )
25          {
26              mergedlist[n1] = initlist[n2];
27          }
28      }
29       else
30      {
31           for ( int  n1 = k,n2 = j;n1 <= n && n2 <= n;n1 ++ ,n2 ++ )
32          {
33              mergedlist[n1] = initlist[n2];
34          }
35      }
36  }
37 
38  void  mergepass( int  initlist[],  int  mergedlist[],  const   int  len, const   int  listlen)
39  {
40       int  i = 0 ;
41       while (i + 2 * len <= listlen - 1 )
42      {
43          merge(initlist,mergedlist,i,i + len - 1 ,i + 2 * len - 1 );
44          i += 2 * len;
45      }
46       if (i + len <= listlen - 1 )
47      {
48          merge(initlist,mergedlist,i,i + len - 1 ,listlen - 1 );
49      }
50       else
51      {
52           for ( int  j = i;j <= listlen - 1 ;j ++ )
53          {
54              mergedlist[j] = initlist[j];
55          }
56      }
57  }
58 
59  void  mergesort( int  list[],  int  listlen)
60  {
61       int   * templist = new   int [listlen];
62       int  len = 1 ;
63       while (len < listlen - 1 )
64      {
65          mergepass(list,templist,len,listlen);
66          len *= 2 ;
67          mergepass(templist,list,len,listlen);
68          len *= 2 ;
69      }
70      delete []templist;
71  }
72 
73  int  main()
74  {
75       int  initlist[] = { 21 , 25 , 49 , 25 , 93 , 62 , 72 , 8 , 37 , 16 , 54 };
76 
77       int  i;
78       for (i = 0 ;i < sizeof (initlist) / sizeof ( int );i ++ )
79          cout << initlist[i] << "   " ;
80      cout << endl;
81      
82      mergesort(initlist, sizeof (initlist) / sizeof ( int ));
83       for (i = 0 ;i < sizeof (initlist) / sizeof ( int );i ++ )
84          cout << initlist[i] << "   " ;
85      cout << endl;
86      
87 
88       return   0 ;
89  }

归并排序的时间复杂度和空间复杂度:

时间复杂度为O(nlgn),空间复杂度为O(n)。实例说明见后。

Multi-pass Sort

在中文翻译中,称其为多通道排序。但是从其描述来看,似乎是多趟排序更为确切。

补充:eaglet提到所谓多通道排序的原型就是B+树。对于B+树没有具体研究过,不过multipass在算法书中似乎没有查找到,倒是B+树会出现,而且看描述似乎的确是一样的。

伪码(using tmp file):

 1  while (not the endof file)
 2     read one record from input file      (I / O Operation)
 3      if (record  in  the region)
 4         put the record into memory
 5      else
 6         write the record into the file(s).  (I / O Operation)
 7     end  if
 8  end  while
 9 
10   sort the records  in  the memory  using  some inner sort method.
11   write the sorted records into the output file.  (I / O Operation)
12  while (there are tmp files left)
13     dump one tmp file (begin from the smallest) to memory
14     sort the records  in  the memory  using  some inner sort method.
15     write the sorted records into the output file.  (I / O Operation)
16  end  while
17  DONE.

伪码(not using tmp file):

 1  for (region ++ )
 2      while (not the endof file)
 3         read one record from input file      (I / O Operation)
 4          if (record  in  the region)
 5             put the record into memory
 6         end  if
 7      end  while
 8      sort the records  in  the memory  using  some inner sort method.
 9      write the sorted records into the output file.  (I / O Operation)
10  end  for
11 DONE

多趟排序的时间复杂度和空间复杂度

可以看到,通过存储到硬盘文件,我们可以控制使用空间的大小,但是这样同样也就加大了I/O读写的次数,而大家都很清楚,I/O操作的效率远远低于内存操作,这样在整个耗时方面,I/O读写次数越多的,其实际运行时间就越长。要提高算法的效率,就需要减少I/O操作的次数。

实例说明见后。

Wonder Sort

OK,现在就进入最精彩的部分,也是这道题目最希望的解法。还记得张柏芝在有一部电影中叫wonderful,很喜欢这个名字,看来作者也很喜欢这个名字哈~

在上面读入文件记录的时候,我们可以使用string, int等类型来表示我们所读入的这一条记录的具体值。而对于32位的机器,其int值为32位,也就是4个byte。而1M空间则有1024*1024=1048576个字节,一共能够表达的int值为262144。而对于10的7次方也就是1千万这样的数,我们除下来得到38.14697265625也就是差不多要做40次。

而Wonder Sort中使用位图来做,以每一位是0还是1表示数是否存在,这样1M空间共有8388608个位,也就能表示大概800万个数。这里我们暂时考虑不存在一个对内存的严格限制。所以如果要表示1000万,我们需要的内存空间大概是1.25M。

伪码:

 1  setup a bit - map which have  1000 , 0000  bits. And  set  all bits to zero.
 2  while (not end of the input file)
 3      read one record from input file
 4      if (correspond bit  in  the bit - map  is   0 )
 5          change the correspond bit  in  the bit - map to  1 . (bit - map[record] = 1 )
 6      else
 7           // if we want to sort, just do nothing.
 8           // if we want to find the num that came twice, just print it out and break.
 9      end  if
10  end  while
11 
12  write the records into the output file.  (I / O Operation)
13 

精彩排序的时间复杂度和空间复杂度

空间复杂度肯定是最低的,而时间复杂度为O(n)。实例见后。

【在该问题上面的扩展】

上面三个解法中,当然是Wonder Sort最好。但是作者也提到了,使用Wonder Sort时,我们需要1.25M的空间(加上其他一些操作,还要更多些,不过最大的需求肯定是1.25M的用来进行位图法的区域),但是如果严格要求使用1M空间的话,我们怎么做?

从上面解法的描述来看,我们可以将第二种解法与第三种解法结合起来,这样就可以解决。

伪码:

 1  setup a bit - map which have  800 , 0000  bits. And  set  all bits to zero.
 2  while (not the endof file)
 3     read one record from input file      (I / O Operation)
 4      if (record  in  the region, which means  0  –  800 , 0000 )
 5          if (correspond bit  in  the bit - map  is   0 )
 6             change the correspond bit  in  the bit - map to  1 . (bit - map[record] = 1 )
 7         else
 8              // if we want to sort, just do nothing.
 9              // if we want to find the num that came twice, just print it out and break.
10       end  if
11     else
12        write the record into the file(s).  (I / O Operation)
13    end  if
14  end  while
15 
16  write the records into the output file.  (I / O Operation)
17 
18  // dump the tmp file (800,0000 – 1000,0000) to memory
19  while (not the endof file)
20      if (correspond bit  in  the bit - map  is   0 )
21          change the correspond bit  in  the bit - map to  1 . (bit - map[record] = 1 )
22      else
23           // if we want to sort, just do nothing.
24           // if we want to find the num that came twice, just print it out and break.
25      end  if
26  end  while
27  write the records into the output file.  (I / O Operation)
28 
29  DONE.
30 

下面就是实例了,在做实例之前,我们有一个问题,就是如何生成题目中要求的测试数据?

测试数据的生成,必须比较随机,我们需要生成范围从0-10000000的数,这里我生成为8000000个数。同时这些数要求不重复。

[回答]

在《编程珠玑》的第12章中给出了回答,这里我直接写出代码。我使用这个生成了一个random.txt文件,一共67.8M。

测试文件生成代码:

 1  #include  < iostream >
 2  #include  < fstream >
 3  using   namespace  std;
 4 
 5  #include  < ctime >
 6  // total use 126 seconds
 7 
 8  ofstream ofs( " random.txt " );
 9 
10  void  myswap( int   & a, int   & b)
11  {
12       int  tmp = a;
13      a = b;
14      b = tmp;
15  }
16 
17  int  bigrand()
18  {
19       return  RAND_MAX * rand() + rand();
20  }
21 
22  int  randint( int  l, int  u)
23  {
24       return  l + bigrand() % (u - l + 1 );
25  }
26 
27  void  generate( int  x[], int  k, int  n)
28  {
29       int  i = 0 ;
30       for (i = 0 ;i < n;i ++ )
31      {
32          x[i] = i;
33      }
34       for (i = 0 ;i < k;i ++ )
35      {
36           // myswap(i,randint(i,n-1));
37           int  j = randint(i,n - 1 );
38           int  t = x[i];
39          x[i] = x[j];
40          x[j] = t;
41          ofs << x[i] << endl;
42      }
43  }
44 
45  int  main()
46  {
47      clock_t Start, Finish;
48      Start  =  clock();
49       int   * x = new   int [ 10000000 ];
50      generate(x, 8000000 , 10000000 );
51       // generate(x,100000,1000000);
52      delete []x;
53      Finish = clock();
54       int  second = double (Finish - Start) / CLOCKS_PER_SEC;
55      cout << " total use  " << second << "  seconds " << endl;
56       return   0 ;
57  }

该代码生成八百万的测试数据共用时126秒,机器配置为1G内存,P4处理器。这里,能否更快生成测试数据,当然,要保证随机性和正确性。

问题

这里我们得到程序的时间是使用clock函数,那如何得到程序占用的内存呢?

还有一个问题就是,我们如何像linux中那样得到用户时间和系统调用时间?

这个还不清楚,这里提出来,大家有知道的可以共享一下。

在测试文件生成好之后,我们就可以来实际的看一下这3种方法所具体使用的时间了。

因为是使用debug版来测试,同时还有其他程序运行,所以可能不是十分精准。但是都是在同一台机器上面测试,所以数量级上面还是可以参考的。

结果:

使用merge sort来排序800万的测试数据,我们共用了337.7秒

使用multipass sort来排序800万的测试数据,我们共用了581.67秒,其实大家仔细看一下,这里我做得不太公平,我这里一趟是使用了一半的数,也就是400万,这样来达到两趟的目的,所以这里来比较是有些问题的。

使用wonder sort时,居然也用了很长时间,共为334.171秒。稍微换了一下,将函数调用去掉一层,最后还是得到total time is 333.328 seconds。

这和我们的预期相差还是比较大的。到底是什么原因?

是否是I/O操作历时比较长的原因?

单纯I/O操作total time is 354.343seconds。

下面列出我使用的代码

1. merge sort

  1  // total running time is 337.751 seconds
  2 
  3  #include  < iostream >
  4  #include  < fstream >
  5  using   namespace  std;
  6 
  7  #include  < ctime >
  8 
  9  ifstream randfile( " random.txt " );
 10  ofstream sortedfile( " sorted.txt " );
 11 
 12  const   int  NUMS = 8000000 ;
 13 
 14  void  merge( int  initlist[],  int  mergedlist[], int  l, int  m,  int  n)
 15  {
 16       int  i = l,j = m + 1 ,k = l;
 17       while (i <= m  &&  j <= n)
 18      {
 19           if (initlist[i] <= initlist[j])
 20          {
 21              mergedlist[k] = initlist[i];
 22              i ++ ;
 23              k ++ ;
 24          }
 25           else
 26          {
 27              mergedlist[k] = initlist[j];
 28              j ++ ;
 29              k ++ ;
 30          }
 31      }
 32       if (i <= m)
 33      {
 34           for ( int  n1 = k,n2 = i;n1 <= n && n2 <= m;n1 ++ ,n2 ++ )
 35          {
 36              mergedlist[n1] = initlist[n2];
 37          }
 38      }
 39       else
 40      {
 41           for ( int  n1 = k,n2 = j;n1 <= n && n2 <= n;n1 ++ ,n2 ++ )
 42          {
 43              mergedlist[n1] = initlist[n2];
 44          }
 45      }
 46  }
 47 
 48  void  mergepass( int  initlist[],  int  mergedlist[],  const   int  len, const   int  listlen)
 49  {
 50       int  i = 0 ;
 51       while (i + 2 * len <= listlen - 1 )
 52      {
 53          merge(initlist,mergedlist,i,i + len - 1 ,i + 2 * len - 1 );
 54          i += 2 * len;
 55      }
 56       if (i + len <= listlen - 1 )
 57      {
 58          merge(initlist,mergedlist,i,i + len - 1 ,listlen - 1 );
 59      }
 60       else
 61      {
 62           for ( int  j = i;j <= listlen - 1 ;j ++ )
 63          {
 64              mergedlist[j] = initlist[j];
 65          }
 66      }
 67  }
 68 
 69  void  mergesort( int  list[],  int  listlen)
 70  {
 71       int   * templist = new   int [listlen];
 72       int  len = 1 ;
 73       while (len < listlen - 1 )
 74      {
 75          mergepass(list,templist,len,listlen);
 76          len *= 2 ;
 77          mergepass(templist,list,len,listlen);
 78          len *= 2 ;
 79      }
 80      delete []templist;
 81  }
 82 
 83  int  main()
 84  {
 85      clock_t start,finish;
 86      start = clock();
 87       int   * initlist = new   int [NUMS];
 88 
 89       int  i;
 90       for (i = 0 ;i < NUMS;i ++ )
 91          randfile >> initlist[i];
 92      
 93      mergesort(initlist,NUMS);
 94       for (i = 0 ;i < NUMS;i ++ )
 95          sortedfile << initlist[i] << endl;
 96      
 97      delete []initlist;
 98 
 99      finish = clock();
100       double  seconds = ( double )(finish - start) / CLOCKS_PER_SEC;
101      cout << " total running time is  " << seconds << "  seconds " << endl;
102       return   0 ;
103  }

2. multipass Sort

 1  // total time is 581.67 seconds
 2 
 3  #include  < iostream >
 4  #include  < fstream >
 5  using   namespace  std;
 6 
 7  #include  < ctime >
 8 
 9  ifstream randfile( " random.txt " );
10  ofstream sortedfile( " sorted.txt " );
11  ifstream helpfileout;
12  ofstream helpfile( " tmp.txt " );
13 
14  int  cmp( const   void   * a,  const   void   * b)
15  {
16       return   * ( int   * )a  -   * ( int   * )b;
17  }
18 
19  void  multipassSort( int  x[])
20  {
21       int  record;
22       int  i = 0 ;
23       int  j;
24       while (randfile >> record)
25      {
26           if (record < 4000000 )
27              x[i ++ ] = record;
28           else
29              helpfile << record << endl;
30      }
31      qsort(x,i, sizeof ( int ),cmp);
32       for (j = 0 ;j < i;j ++ )
33          sortedfile << x[j] << endl;
34      i = 0 ;
35      helpfile.close();
36      helpfileout.open( " tmp.txt " );
37       while (helpfileout >> record)
38      {
39          x[i ++ ] = record;
40      }
41      qsort(x,i, sizeof ( int ),cmp);
42       for (j = 0 ;j < i;j ++ )
43          sortedfile << x[j] << endl;
44  }
45 
46  int  main()
47  {
48      clock_t start,finish;
49      start = clock();
50       int   * x = new   int [ 8000000 ];
51      multipassSort(x);
52      delete []x;
53 
54      finish = clock();
55       double  secs = ( double )(finish - start) / CLOCKS_PER_SEC;
56      cout << " total time is  " << secs << "  seconds " << endl;
57       return   0 ;
58  }
59 

3. wonder Sort

 1  #include  < iostream >
 2  #include  < fstream >
 3  using   namespace  std;
 4 
 5  #include  < ctime >
 6 
 7  ifstream randfile( " random.txt " );
 8  ofstream sortedfile( " sorted.txt " );
 9 
10  const   int  NUMS = 8000000 ;
11 
12  const   int  BITSPERINT = 32 ;
13  const   int  SHIFT = 5 ;
14  const   int  MASK = 0x1f ;
15 
16  void  seti( int  x[], int  i)
17  {
18      x[i >> SHIFT]  |=  ( 1 << (i  &  MASK));
19  }
20 
21  void  clri( int  x[], int  i)
22  {
23      x[i >> SHIFT]  &=   ~ ( 1 << (i  &  MASK));
24  }
25 
26  int  test( int  x[], int  i)
27  {
28       return  x[i >> SHIFT]  &  ( 1 << (i  &  MASK));
29  }
30 
31  void  wonderSort( int  x[])
32  {
33       int  tmp;
34       int  i = 0 ;
35       for (i = 0 ;i < NUMS;i ++ )
36      {
37          randfile >> tmp;
38           if (test(x,tmp) == 0 )
39          {
40              seti(x,tmp);
41          }
42      }
43       for (i = 0 ;i < 10000000 ;i ++ )
44      {
45           if (test(x,i) != 0 )
46          {
47              sortedfile << i << endl;
48          }
49      }
50  }
51 
52  int  main()
53  {
54      clock_t start,finish;
55      start = clock();
56       int   * x = new   int [ 10000000 / BITSPERINT];
57      memset(x, 0 , 10000000 / BITSPERINT * sizeof ( int ));
58 
59      wonderSort(x);
60      delete[] x;
61      finish = clock();
62       double  seconds = ( double )(finish - start) / CLOCKS_PER_SEC;
63      cout << " total use time is  " << seconds << "  seconds " << endl;
64 
65       return   0 ;
66  }

4. 单纯读写文件

 1  #include  < iostream >
 2  #include  < fstream >
 3  using   namespace  std;
 4 
 5  #include  < ctime >
 6 
 7  ifstream randfile( " random.txt " );
 8  ofstream outfile( " out.txt " );
 9 
10  #define  NUMS 8000000
11 
12  int  main()
13  {
14      clock_t start,finish;
15      start = clock();
16       int  i;
17       int  tmp;
18       for (i = 0 ;i < NUMS;i ++ )
19      {
20          randfile >> tmp;
21          outfile << tmp;
22      }
23      finish = clock();
24       double  secs = ( double )(finish - start) / CLOCKS_PER_SEC;
25      cout << " total time is  " << secs << " seconds " << endl;
26 
27       return   0 ;
28  }

如果不使用文件读写,就可以看出算法的效率来了,但是如何做到呢?

排序部分结束,然后回到面试题,如果只是来查找是否有重复数的话,是否有其他解法,如何做?

在上次的回复中,winter-cn提到了字典树和哈希表的解决方案。

字典树的确是一个好办法,而且仅仅是对于查找,如果是排序,字典树就不合适了。

而哈希还没有想到好的哈希函数,具体也没有细想,但是应该也是可以的。

【在其基础上衍生的面试问题】

其实上面的内容都解决了的话,那一开始的面试题也就解决了,因为其尽管问题规模变大了,但是其能够使用的内存也一样变大了,其基本方法还是一样的。

现在很多公司,因为其筛选人员的目的,同时也由于其工作是处理海量数据,所以在面试的时候,会出一些这样的关于海量数据处理的问题,但是我们很多人,包括我,都一般不会接触到这样海量的数据,所以,适量的减小问题的规模,但是同时将其内存限制变得更加严格,其实其本质还是一样的。

【TODO – 海量数据处理的话题】

这里的话题可以归入“海量数据处理”,关于海量数据处理,现在有很多公司的面试题会提相关的问题,如果没有对这个话题思考过的话,是不太可能会有很好的答案的,关于这个话题,以后还可以找到其他的问题来进行讨论,当问题规模不大的时候,体现不出算法的优势,但是当问题的规模到达一定数量级的时候,O(n)或者O(lgn)的算法的优势就能够体现出来了。

因为内容比较多,整理也花了一些时间,还有编写代码,如果其中有错误,欢迎大家指出,本来想分为几篇来写的,最后还是一下子写成一篇写完算了,篇幅就比较长,而且代码也较多,多谢大家能够看到最后~

面试题之10亿正整数问题--完整解答相关推荐

  1. 2015百度面试题--对10亿个32位整数去重和排序

    对放在文件中的10亿个32位整数进行去重和排序 :10亿个32位整数的大小约为4GB,这里假设电脑的内存放不下.使用bit位图能够很快解决该问题(其实思想类似于哈希),使用10亿个比特位来表示每个数, ...

  2. 10亿int型数,统计只出现一次的数

    原文:http://blog.csdn.net/u010983881/article/details/75097358 题目 10亿int整型数,以及一台可用内存为1GB的机器,时间复杂度要求O(n) ...

  3. 【算法】10亿int型数,统计只出现一次的数

    题目 10亿int整型数,以及一台可用内存为1GB的机器,时间复杂度要求O(n),统计只出现一次的数? 分析 首先分析多大的内存能够表示10亿的数呢?一个int型占4字节,10亿就是40亿字节(很明显 ...

  4. C++统计10亿以内所有的质素(素数)的实现算法(附完整源码)

    C++统计10亿以内所有的质素的实现算法 C++统计10亿以内所有的质素的实现算法完整源码(定义,实现,main函数测试) C++统计10亿以内所有的质素的实现算法完整源码(定义,实现,main函数测 ...

  5. 极兔一面:10亿级ES海量搜索狂飙10倍,该怎么办?

    背景说明: ES高性能全文索引,如果不会用,或者没有用过,在面试中,会非常吃亏. 所以ES的实操和底层原理,大家要好好准备. 另外,ES调优是一个非常.非常核心的面试知识点,大家要非常重视. 在40岁 ...

  6. c语言考试编程题万能公式,C语言程序设计历年统考试题集10套含答案(可编辑)

    <C语言程序设计历年统考试题集10套含答案(可编辑)>由会员分享,可在线阅读,更多相关<C语言程序设计历年统考试题集10套含答案(可编辑)(39页珍藏版)>请在人人文库网上搜索 ...

  7. 目标10亿部?苹果AR眼镜有望明年登场!传搭载Mac级处理器、4K显示屏

      视学算法报道   编辑:好困 David [新智元导读]苹果的AR设备终于要来了?昨日,知名分析师郭明錤再次预测,苹果AR头显将于2022年第四季度登场!据悉,这款设备将搭载Mac级处理器.4K显 ...

  8. 每年“骗”马云10亿,被骂大忽悠,他却当选中国工程院院士?

    从来都是马云"骗"我们钱 把我们的钱包掏得空空的 那么你见过有人"骗"马云的钱吗? 见了一面就"骗"了马云10亿 整整10年! 这个人就是马 ...

  9. 【面试现场】如何在10亿数中找出前1000大的数

    小史是一个应届生,虽然学的是电子专业,但是自己业余时间看了很多互联网与编程方面的书,一心想进BAT互联网公司. 之前小史在BAT三家的面试中已经挂了两家,今天小史去了BAT中的最后一家面试了. 简单的 ...

  10. 日10亿级处理,基于云的微服务架构

    德比软件:基于云的微服务架构 作者:朱攀,德比软件架构师,同济大学研究生,2007 年 2 月加入德比软件(DerbySoft),拥有 10 年以上的软件架构和开发经验.目前主要负责公司数据对接平台的 ...

最新文章

  1. javabean和EJB的区别
  2. 线段树练习 3P3372 【模板】线段树 1
  3. java performance tools / NetBeans Profiler / Sun BTrace / Eclipse MAT / IBM ISA
  4. java是什么偏旁部首_Python实现获取汉字偏旁部首的方法示例【测试可用】
  5. 【堆内存】动态图+代码五分钟轻松理解学会
  6. 编程语言python入门-编程语言入门(以python为例)
  7. 实体词典 情感词典_情感词典
  8. mysql数据恢复(根据.ibd文件恢复数据)
  9. 计算机c盘突然少了几个G,做系统时c盘显示0容量-关于Windows系统c盘突然没了十几个g...
  10. Web前端下载文件的几种常见方式
  11. unity之摇杆和NPC
  12. 输出三位数的个十百位数
  13. MySQL及达梦数据库数字金额转人民币大写
  14. 计算机故障维修要遵循什么原则,超级实用的六条法则教你快速搞定电脑故障维修!...
  15. 新浪短域名和百度短域名
  16. java返回当年的天数_获取Java中当年剩余的天数
  17. GhostNet详解及代码实现
  18. cps网店php源码,100%开源程序 PHP源码 页游联运系统 CPA+CPS
  19. 如何使用ArcGIS裁剪栅格图
  20. Eclipse 是什么?

热门文章

  1. 双线 路由表 linux,linux双线ip设置(不需额外增加路由表)
  2. Git的诞生_繁星漫天_新浪博客
  3. 计算机辅助设计基础试题,CAD基础试题「附答案」
  4. uniapp使用uni-ui插件的方式
  5. IDEA突然不能输入中文
  6. 关于获取日周月的时间处理与日期联动处理
  7. docker容器获取宿主机IP
  8. excel制作特殊图表记录
  9. 小程序发布新版本后,部分用户手机白屏
  10. 超市密码箱c语言程序,超市存包系统C语言.doc