Careercup - Microsoft面试题 - 5943729928011776

2014-05-10 21:56

题目链接

原题:

Suppose you get number of unique users every second from bing 
For eg, 2,4,5,1,2,etc 
You need to write a web service method , such that it takes the input n, which return lowest n unique number from the list of unique numbers. For eg, if n is 3 then you need to return 2,1,2

题目:从n个数里找出m个最小的数。

解法1:题目虽然没有要求结果是否有序,也没有说算法是否是在线的。那么肯定是有两种解法的。第一种就是O(n * log(m))的最大堆法。能提供有序的结果。如果要求在线算法的话,堆仍能满足要求。

代码:

 1 // http://www.careercup.com/question?id=5943729928011776
 2 #include <iostream>
 3 #include <queue>
 4 #include <vector>
 5 using namespace std;
 6 
 7 template <class T>
 8 struct myless {
 9     bool operator () (const T &x, const T &y) {
10         return x < y;
11     };
12 };
13 
14 int main()
15 {
16     int val;
17     int n, k;
18     int i;
19     // max heap
20     priority_queue<int, vector<int>, myless<int> > q;
21     vector<int> v;
22     
23     while (cin >> n >> k && (n > 0 && k > 0)) {
24         k = k < n ? k : n;
25         for (i = 0; i < k; ++i) {
26             cin >> val;
27             q.push(val);
28         }
29         
30         for (i = k; i < n; ++i) {
31             cin >> val;
32             if (q.top() > val) {
33                 q.pop();
34                 q.push(val);
35             }
36         }
37         while (!q.empty()) {
38             v.push_back(q.top());
39             q.pop();
40         }
41         reverse(v.begin(), v.end());
42         
43         cout << '{';
44         for (i = 0; i < k; ++i) {
45             i ? (cout << ' '), 1 : 1;
46             cout << v[i];
47         }
48         cout << '}' << endl;
49         
50         v.clear();
51     }
52     
53     return 0;
54 }

解法2:快速选择算法可以在O(n)时间找出第k大的数,不过写法复杂,并且运行的实际效率由于常系数很大,递归不稳定等缺点,使得这算法很多时候只是看上去很美。利用这个算法得到第m大的数之后,再扫描一次整个数组就能得到最小的m个数了。这个算法不能在线进行,因为快速选择算法的思想源自快速排序,是不稳定的内存排序算法。

代码:

  1 // http://www.careercup.com/question?id=5943729928011776
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <vector>
  5 using namespace std;
  6 
  7 const int CUT_OFF = 3;
  8 
  9 int medianThree(vector<int> &v, int ll, int rr)
 10 {
 11     int mm = (ll + rr) / 2;
 12 
 13     if (v[ll] > v[mm]) {
 14         swap(v[ll], v[mm]);
 15     }
 16     if (v[ll] > v[rr]) {
 17         swap(v[ll], v[rr]);
 18     }
 19     if (v[mm] > v[rr]) {
 20         swap(v[mm], v[rr]);
 21     }
 22     swap(v[mm], v[rr - 1]);
 23     return v[rr - 1];
 24 }
 25 
 26 void quickSelect(vector<int> &v, int ll, int rr, int k)
 27 {
 28     // reference from "Data Structure and Algorithm Analysis in C" by Mark Allen Weiss.
 29     int pivot;
 30     int i, j;
 31     
 32     if (ll + CUT_OFF <=    rr) {
 33         pivot = medianThree(v, ll, rr);
 34         i = ll;
 35         j = rr - 1;
 36         
 37         while (true) {
 38             while (v[++i] < pivot);
 39             while (v[--j] > pivot);
 40             if (i > j) {
 41                 break;
 42             }
 43             swap(v[i], v[j]);
 44         }
 45         swap(v[i], v[rr - 1]);
 46     
 47         if (k < i) {
 48             return quickSelect(v, ll, i - 1, k);
 49         } else if (k > i) {
 50             return quickSelect(v, i + 1, rr, k);
 51         }
 52     } else {
 53         for (i = ll; i <= rr; ++i) {
 54             for (j = i + 1; j <= rr; ++j) {
 55                 if (v[i] > v[j]) {
 56                     swap(v[i], v[j]);
 57                 }
 58             }
 59         }
 60     }
 61 }
 62 
 63 int main()
 64 {
 65     vector<int> v;
 66     vector<int> res;
 67     int n, k;
 68     int i;
 69     int k_small, count;
 70     
 71     while (cin >> n >> k && (n > 0 && k > 0)) {
 72         v.resize(n);
 73         for (i = 0; i < n; ++i) {
 74             cin >> v[i];
 75         }
 76 
 77         // find the kth smallest number
 78         // this will change the order of elements
 79         quickSelect(v, 0, n - 1, k - 1);
 80         k_small = v[k - 1];
 81         count = k;
 82         for (i = 0; i < n; ++i) {
 83             if (v[i] < k_small) {
 84                 --count;
 85             }
 86         }
 87         for (i = 0; i < n; ++i) {
 88             if (v[i] < k_small) {
 89                 res.push_back(v[i]);
 90             } else if (v[i] == k_small && count > 0) {
 91                 res.push_back(v[i]);
 92                 --count;
 93             }
 94         }
 95         
 96         cout << '{';
 97         for (i = 0; i < k; ++i) {
 98             i ? (cout << ' '), 1 : 1;
 99             cout << res[i];
100         }
101         cout << '}' << endl;
102         
103         v.clear();
104         res.clear();
105     }
106     
107     return 0;
108 }

 

转载于:https://www.cnblogs.com/zhuli19901106/p/3721090.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值