Last active
February 6, 2017 22:35
-
-
Save luangong/4663453 to your computer and use it in GitHub Desktop.
陈利人老师微博面试编程题:一个有序数组(从小到大排列),数组中的数据有正有负,求这个数组中的最小绝对值。微博地址:http://weibo.com/1915548291/zgH8XdILh 解决思路:二分查找。注意边界情况的处理
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 陈利人老师微博面试编程题:一个有序数组(从小到大排列),数组中的数据有正有负, | |
* 求这个数组中的最小绝对值。 | |
* | |
* Sample Input | |
* | |
* -4 -2 -1 2 3 5 | |
* -2 0 3 5 8 | |
* -8 -6 -3 -2 1 | |
* | |
* http://weibo.com/1915548291/zgH8XdILh | |
* | |
* 解决思路:二分查找 | |
*/ | |
#include <iostream> | |
#include <sstream> | |
#include <limits> | |
#include <vector> | |
#include <iterator> | |
#include <algorithm> | |
using namespace std; | |
int minAbs(int *A, int beg, int end) { | |
if (beg >= end) { | |
return numeric_limits<int>::max(); | |
} | |
// 如果最左边最小的数大于或等于 0,则右边的数必然为非负且绝对值不小于此数, | |
// 所以最左边的数就是要求的最小的绝对值 | |
if (A[beg] >= 0) { | |
return A[beg]; | |
} | |
// 如果最右边最大的数小于或等于 0,则左边的数必然为非正且绝对值不小于此数, | |
// 所以最右边的数就是要求的最小的绝对值(注意要取反) | |
if (A[end-1] <= 0) { | |
return -A[end-1]; | |
} | |
// 否则进行二分,求得数组中间的数 | |
int mid = beg + (end - beg) / 2; | |
// 如果中间的数为非负,那么可以排除掉右半边的数 | |
if (A[mid] >= 0) { | |
return min(A[mid], minAbs(A, beg, mid)); | |
} else { // 否则排除掉左半边的数 | |
return min(-A[mid], minAbs(A, mid + 1, end)); | |
} | |
} | |
int main(int argc, char **argv) { | |
// 输入数据有多组,每组占一行,各个数字间用空格隔开 | |
string line; | |
while (getline(cin, line)) { | |
istringstream strm(line); | |
vector<int> vec; | |
copy(istream_iterator<int>(strm), | |
istream_iterator<int>(), back_inserter(vec)); | |
sort(vec.begin(), vec.end()); | |
cout << minAbs(&vec[0], 0, vec.size()) << endl; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@darrenhp 你的思路是对的,很简洁,这个题目是 N 年前的了,当时没想到,没必要自己手写二分查找算法