百度面试题:求绝对值最小的数
参考了这篇博客的内容和思路:http://www.cnblogs.com/nokiaguy/archive/2013/01/29/2881476.html
有一个已经排序的数组(升序),数组中可能有正数、负数或0,求数组中元素的绝对值最小的数,要求,不能用顺序比较的方法(复杂度需要小于O(n)),可以使用任何语言实现
例如,数组{-20,-13,-4, 6, 77,200} ,绝对值最小的是-4。
算法实现的基本思路
三种情况:
全负数 全正数 正负皆有
1:取最右 时间复杂度为o(1)
2:取最左 时间复杂度为o(1)
3:二分查找0, 找到为最小,否则最后查找区间,左右取绝对值最小,时间复杂度为o(log2 n)
解法一:

1 private static IEnumerable<int> GetABSMinValue1(IList<int> arr) 2 { 3 var ret = new List<int>(); 4 if (arr.Count < 2) 5 { 6 ret.Add(arr[0]); 7 } 8 else 9 { 10 if (arr[arr.Count - 1] <= 0) 11 { 12 ret.Add(arr[arr.Count - 1]); 13 } 14 else if (arr[0] >= 0) 15 { 16 ret.Add(arr[0]); 17 } 18 else 19 { 20 //方法一:循环遍历法 21 for (int i = 0; i < arr.Count; i++) 22 { 23 if (arr[i] < 0 && arr[i + 1] >= 0) 24 { 25 if (Math.Abs(arr[i]) > Math.Abs(arr[i + 1])) 26 { 27 ret.Add(arr[i + 1]); 28 } 29 else if (Math.Abs(arr[i]) < Math.Abs(arr[i + 1])) 30 { 31 ret.Add(arr[i]); 32 } 33 else 34 { 35 ret.Add(arr[i]); 36 ret.Add(arr[i + 1]); 37 } 38 } 39 } 40 } 41 } 42 43 return ret; 44 }
解法二:

1 private static IEnumerable<int> GetABSMinValue2(IList<int> arr) 2 { 3 var ret = new List<int>(); 4 if (arr.Count < 2) 5 { 6 ret.Add(arr[0]); 7 } 8 else 9 { 10 if (arr[arr.Count - 1] <= 0) 11 { 12 ret.Add(arr[arr.Count - 1]); 13 } 14 else if (arr[0] >= 0) 15 { 16 ret.Add(arr[0]); 17 } 18 else 19 { 20 //方法二:第一步是二分法,第二步循环遍历法 21 int low = 0, high = arr.Count - 1, mid; 22 while (low <= high) 23 { 24 mid = (low + high) / 2; 25 if (arr[mid] == 0) 26 ret.Add(arr[mid]); 27 if (arr[mid] > 0) //中间位置为正数 28 { 29 if (arr[mid - 1] < 0) //中间位置前一个为负数 30 { 31 if (Math.Abs(arr[mid - 1]) == arr[mid]) 32 { 33 ret.Add(arr[mid - 1]); 34 ret.Add(arr[mid]); 35 } 36 else 37 { 38 ret.Add(Math.Abs(arr[mid - 1]) > arr[mid] ? arr[mid] : arr[mid - 1]); 39 } 40 break; 41 } 42 high = mid - 1; 43 } 44 else //中间位置为负数 45 { 46 if (arr[mid + 1] > 0) //中间位置后一个为正数 47 { 48 if (Math.Abs(arr[mid]) == arr[mid + 1]) 49 { 50 ret.Add(arr[mid]); 51 ret.Add(arr[mid + 1]); 52 } 53 else 54 { 55 ret.Add(Math.Abs(arr[mid]) > arr[mid + 1] ? arr[mid + 1] : arr[mid]); 56 } 57 break; 58 } 59 low = mid + 1; 60 } 61 } 62 } 63 } 64 65 return ret; 66 }
解法三:

1 private static void binarySearch(int low, int high, IList<int> arr, ref List<int> ret) 2 { 3 while (low <= high) 4 { 5 int mid = (low + high) / 2; 6 if (arr[mid] == 0) 7 { 8 ret.Add(arr[mid]); 9 break; 10 } 11 if (arr[mid] > 0) //中间位置为正数 12 { 13 if (arr[mid - 1] < 0) //中间位置前一个为负数 14 { 15 if (Math.Abs(arr[mid - 1]) == arr[mid]) 16 { 17 ret.Add(arr[mid - 1]); 18 ret.Add(arr[mid]); 19 } 20 else 21 { 22 ret.Add(Math.Abs(arr[mid - 1]) > arr[mid] ? arr[mid] : arr[mid - 1]); 23 } 24 break; 25 } 26 high = mid - 1; 27 binarySearch(low, high, arr, ref ret); 28 break; 29 } 30 else //中间位置为负数 31 { 32 if (arr[mid + 1] > 0) //中间位置后一个为正数 33 { 34 if (Math.Abs(arr[mid]) == arr[mid + 1]) 35 { 36 ret.Add(arr[mid]); 37 ret.Add(arr[mid + 1]); 38 } 39 else 40 { 41 ret.Add(Math.Abs(arr[mid]) > arr[mid + 1] ? arr[mid + 1] : arr[mid]); 42 } 43 break; 44 } 45 low = mid + 1; 46 binarySearch(low, high, arr, ref ret); 47 break; 48 } 49 } 50 } 51 52 private static IEnumerable<int> GetABSMinValue3(IList<int> arr) 53 { 54 var ret = new List<int>(); 55 if (arr.Count < 2) 56 { 57 ret.Add(arr[0]); 58 } 59 else 60 { 61 if (arr[arr.Count - 1] <= 0) 62 { 63 ret.Add(arr[arr.Count - 1]); 64 } 65 else if (arr[0] >= 0) 66 { 67 ret.Add(arr[0]); 68 } 69 else 70 { 71 //方法三:二分法 72 binarySearch(0, arr.Count - 1, arr, ref ret); 73 } 74 } 75 76 return ret; 77 }
测试用例:

1 var arr1 = new[] { -23, -22, -3, -2,-1, 1, 2, 3, 5, 20, 120 }; 2 var arr2 = new[] { -23, -22, -12, -6, -4 }; 3 var arr3 = new[] { 1, 22, 33, 55, 66, 333 }; 4 Console.WriteLine(string.Join(",", GetABSMinValue1(arr1))); 5 Console.WriteLine(string.Join(",", GetABSMinValue1(arr2))); 6 Console.WriteLine(string.Join(",", GetABSMinValue1(arr3))); 7 Console.WriteLine(string.Join(",", GetABSMinValue2(arr1))); 8 Console.WriteLine(string.Join(",", GetABSMinValue2(arr2))); 9 Console.WriteLine(string.Join(",", GetABSMinValue2(arr3))); 10 Console.WriteLine(string.Join(",", GetABSMinValue3(arr1))); 11 Console.WriteLine(string.Join(",", GetABSMinValue3(arr2))); 12 Console.WriteLine(string.Join(",", GetABSMinValue3(arr3))); 13 Console.ReadKey();
如果有更好的解决方案,请指教。谢谢大家!
源码下载地址:GetABSMinValue.rar
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?