找出有序数组中绝对值最小的元素

来源:互联网 发布:网络信息安全的问题 编辑:程序博客网 时间:2024/05/25 23:56

给定一个有序整数序列(非递减序),可能包含负数,找出其中绝对值最小的元素,比如给定序列 -5, -3, -1, 2, 8 则返回-1。

思路:

由于给定序列是有序的,而这又是搜索问题,所以首先想到二分搜索法,只不过这个二分法比普通的二分法稍微麻烦点,可以分为下面几种情况

  • 如果给定的序列中所有的数都是正数,那么数组的第一个元素即是结果。
  • 如果给定的序列中所有的数都是负数,那么数组的最后一个元素即是结果。
  • 如果给定的序列中既有正数又有负数,那么绝对值得最小值一定出现在正数和负数的连接处。
代码如下:


[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <math.h>  
  3. #include <stdlib.h>  
  4.   
  5. #define true 1  
  6. #define false 0  
  7.   
  8. int SameSign(int a, int b)  
  9. {  
  10.     if (a * b > 0)  
  11.         return true;  
  12.     else  
  13.         return false;  
  14. }  
  15.   
  16. // 找出一个非递减序整数序列中绝对值最小的数  
  17. int MinimumAbsoluteValue(int* a, int n){  
  18.     // Only one number in array  
  19.     if (n == 1)  
  20.     {  
  21.         return a[0];  
  22.     }  
  23.       
  24.     // All numbers in array have the same sign  
  25.     if (SameSign(a[0], a[n-1]))  
  26.     {  
  27.         return (a[0]>=0)? a[0] : a[n-1] ;  
  28.     }  
  29.       
  30.     // Binary search  
  31.     int l = 0 ;  
  32.     int r = n-1 ;  
  33.       
  34.     while(l < r)  
  35.     {  
  36.         if (l + 1 == r)  
  37.         {  
  38.             return abs(a[l]) < abs(a[r]) ? a[l] : a[r] ;  
  39.         }  
  40.           
  41.         int m = (l + r) /2 ;  
  42.           
  43.         if (SameSign(a[m], a[r]))  
  44.         {  
  45.             r = m;  
  46.         }  
  47.         else  
  48.         {  
  49.             l = m ;  
  50.         }  
  51.     }  
  52.     return -1;  
  53. }  
  54.   
  55. int main(int argc, const char * argv[])  
  56. {  
  57.     int a[5] = {-3,-2,-1,5,6};  
  58.     printf("%d\n",MinimumAbsoluteValue(a, 5));  
  59.     return 0;  
  60. }  
阅读全文
0 0
原创粉丝点击