剑指Offer----扩展:有趣的数字(腾讯)

来源:互联网 发布:福州seo服务 编辑:程序博客网 时间:2024/06/05 05:55

问题描述:


小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?

输入描述:
输入包含多组测试数据。对于每组测试数据:
N - 本组测试数据有n个数
a1,a2...an - 需要计算的数据
保证:1<=N<=100000,0<=ai<=INT_MAX.

输出描述:
对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。

输入例子:
6
45 12 45 32 5 6

输出例子:
1 2

方法一:


分析:使用一个容器,将数组中两两数之差的绝对值放到到map容器中,如果差值相同,则map中对应的值加1,这种方法的缺点就是时间复杂度高,空间复杂度也高!!!双高!!!但是最容易想到!!!


源代码:

#include<iostream>#include<map>using namespace std;int main(){int n;while (cin>>n){int *arr = new int[n];for (int i = 0; i < n; ++i)cin >> arr[i];map<int, int> mmap;int max = -INT_MAX;int min = INT_MAX;for (int i = 0; i < n - 1; ++i){for (int j = i+1; j < n; ++j){int result = arr[i] - arr[j];result = result >= 0 ? result : -result;if (result < min)min = result;if (result > max)max = result;mmap[result]++;}}cout << mmap[min] << " " << mmap[max] << endl;delete[] arr;}cout << __DATE__ << "  " << __TIME__ << endl;system("pause");return 0;}

运行结果:
61 2 3 4 5 65 161 1 2 2 3 33 461 1 1 1 1 115 15^ZAug 28 2016  16:30:47请按任意键继续. . .


方法二:

分析:先将数组排序,那么最大的差值肯定就是最大数减去最小数,最小的差值肯定就是两个相邻数的差值,还有就是特殊情况的处理,当数组中所有的数字都相同的时候的处理,当最小的差值为0的时候的情况的处理!


源代码:

#include<iostream>#include<vector>#include<algorithm>using namespace std;int main(){int n;while (cin >> n){if (n == 1)//如果只有一个数字的话{cout << 0 << " " << 0 << endl;continue;}if (n == 2)//如果只有两个数字的话{cout << 1 << " " << 1 << endl;}//含有3个以上的数字vector<int> data;while (n--){int temp;cin >> temp;data.push_back(temp);}int len = data.size();sort(data.begin(), data.end());int min = data[1] - data[0];//最小的差值不一定是是头两个元素之差,但一定是相邻的元素之差for (int i = 2; i < len; ++i){if ((data[i] - data[i - 1]) < min)min = data[i] - data[i - 1];}int min_count = 0;if (min == 0)//此时,应该找到元素相同的区域块,可能有很多块{for (int i = 1; i < len; ++i){int j = i - 1;while (j >= 0 && data[i] == data[j]){++min_count;--j;}}}else//此时,应该是两个相邻的元素只差{for (int i = 1; i < len; ++i){if ((data[i] - data[i - 1]) == min)min_count++;}}//最大差的数肯定是最右边的数减去最左边的数int max = data[len - 1] - data[0];int max_count = 0;//如果最大的数字不等于最小的数字,则统计最小数字的个数,统计最大数字的个数,相乘既得结果if (data[0] != data[len - 1]){int num_min = 1;for (int i = 1; i < len - 1; ++i){if (data[i] == data[0])num_min++;elsebreak;}int num_max = 1;for (int i = len - 2; i >= 0; --i){if (data[i] == data[len - 1])num_max++;elsebreak;}max_count = num_min*num_max;}else//如果最大的数字等于最小的数字{max_count = len*(len - 1) / 2;}cout << min_count << " " << max_count << endl;}cout << __DATE__ << "  " << __TIME__ << endl;system("pause");return 0;}

运行结果:
61 2 3 4 5 65 161 1 2 2 3 33 461 1 1 1 1 115 15^ZAug 28 2016  16:34:42请按任意键继续. . .






0 0