面试题目

来源:互联网 发布:js 浮点数比较 编辑:程序博客网 时间:2024/04/29 08:57

问题描述:

多人排成一个队列,我们认为从低到高是正确的序列,但是总有部分人不遵守秩序。如果说,前面的人比后面的人高(两人身高一样认为是合适的),那么我们就认为这两个人是一对“捣乱分子”。

比如说,现在存在一个序列: 176, 178, 180, 170, 171
这些捣乱分子对为:<176, 170>, <176, 171>, <178, 170>, <178, 171>, <180, 170>, <180, 171>
那么,现在给出一个整型序列,请找出这些捣乱分子对的个数(仅给出捣乱分子对的数目即可,不用具体的对。
 要求:
 输入:
 为一个文件(in),文件的每一行为一个序列。序列全为数字,数字间用”,”分隔。
 输出:
 为一个文件(out),每行为一个数字,表示捣乱分子的对数。
 详细说明自己的解题思路,说明自己实现的一些关键点。
 并给出实现的代码,并分析时间复杂度。
 限制:
 输入每行的最大数字个数为100000 个,数字最长为6 位。程序无内存使用限制。


解决思想:

研究题意,其实就是让我们找到所有大于当前数且在其之前出现的数的个数,当读懂题意后,我首先想到的是采用BF来找出所有的捣乱份子对,即针对每一个数a[i],查找a[0...i-1]中的每一个数,如果比它大,则是捣乱分子,记录增1,直到所有的数遍历完。采用该方法空间复杂度为O(1),但时间复杂度O(N^2)。

由于题目要求不限制内存的使用,可考虑采用更高效的方法来降低时间复杂度,即空间换时间。想到这里,大家一定想到了那种排序方法既是稳定的,其时间复杂度又是O(N*lgN),对,合并排序。

本题也可采用合并排序思想来求解,同时也引入了分治的思想:

(1)先将待求解的元素划分为两个较小部分,分别求得两部分的捣乱分子对的个数,同时对元素进行排序。

(2)对已排序的两个部分进行合并,在合并时如果后半部分的值位于前半部分(插入的位置),则捣乱分子对增加j - low - k(见源码)。

 (3)返回所求得得捣乱分子对个数。

通过合并于分治思想,空间复杂度为O(N),时间复杂度降低到O(N*lgN)。

以下部分为源码(已测):

[cpp] view plaincopy
  1. int count_trouble_makers(int *array, int low, int high)  
  2. {  
  3.     if (low >= high)  
  4.     {  
  5.         return 0;  
  6.     }  
  7.     int count, halfpart;  
  8.     halfpart = (low + high) / 2;  
  9.     count = count_trouble_makers(array, low, halfpart) + count_trouble_makers(array, halfpart + 1, high);   
  10.     int i, j, k, *tarray;   
  11.     tarray = new int[high - low + 1];  
  12.     for (k = 0, i = low, j = halfpart + 1; i <= halfpart && j <= high;)  
  13.     {  
  14.         if (array[i] > array[j])  
  15.         {  
  16.             tarray[k] = array[j];  
  17.             count += j - low - k;  
  18.             ++j;  
  19.             ++k;  
  20.         } else {  
  21.             tarray[k++] = array[i];  
  22.             i++;  
  23.         }  
  24.     }  
  25.     while(i <= halfpart) {  
  26.         tarray[k++] = array[i++];  
  27.     }  
  28.     while(j <= high) {  
  29.         tarray[k++] = array[j++];  
  30.     }  
  31.     for (k = 0, i = low; i <= high; ++i, ++k)  
  32.     {  
  33.         array[i] = tarray[k];  
  34.     }  
  35.     delete []tarray;  
  36.     re
0 0
原创粉丝点击