Swift 有序数组获取绝对值最小的数

351 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情 如果哪里写的不对,请大家评论批评。

题目

在有序(升序,无重复,可能是正或者负数)的整数数组,获取绝对值最小的数。要求不能顺序比较,时间复杂度小于O(n)。

输入:一个有序的整数数组

输出:绝对值最小的数

分析

首先可以确定数字是升序

  1. 如果数组第一个数是非负数,那么第一个肯定数组绝对值最小的。例如:[0,1,2,3,4,5,7]
  2. 如果数组的最后一个元素是负数,那最后一个的绝对值是最小的。例如:[-9,-8,-6,-4,-2,-1]
  3. 数组程度需要大于0
  4. 如果数组长度是1,那么只能是这个数
  5. 如果数组长度是2,那么两种直接比较即可
  6. 剩下的情况就只有数组长度大于三,且数组既有负数也有整数,可以使用二分查找方式找到中间的数字进行比较,从而找到最小数

代码

func getMinAbsoulteValue(_ list :Array<Int>) -> Int{
    if list.isEmpty {
        return 0
    }

    if let first = list.first,first >= 0 {
        return first
    }

    if let last = list.last,last <= 0 {
        return last
    }
    
    if list.count == 1 {
        return list.first!
    }
    
    if list.count == 2 {
        if abs(list.first!) > abs(list[1]){
            return list[1]
        }else{
            return list.first!
        }
    }

    var left = 0
    var right = list.count - 1
    var mid = (left + right) / 2
    while true {
        if list[mid] == 0 {
            return list[mid]
        }
        let mida = abs(list[mid - 1])
        let midz = abs(list[mid + 1])
        let midd = abs(list[mid])
        if ((midd < midz)) && (midd < mida) {
            return list[mid]
        }
        
        if midd < midz {
            right = mid + 1
        }
        
        if midd < mida {
            left = mid - 1
        }
        mid = (left + right) / 2
    }
}

let listS1 = [-9,-5,-3,-1,0, 2 ,3 ,6,7,8,9,11,12,13,14,15,16,17,18,21,22]
let listS2 = [0,1,2,3,4,5,6]
let listS3 = [-10,-9,-8,-3,-2,-1]
let listS4 = [-10]
let listS5 = [-10,1]
print(getMinAbsoulteValue(listS1))
print(getMinAbsoulteValue(listS2))
print(getMinAbsoulteValue(listS3))
print(getMinAbsoulteValue(listS4))
print(getMinAbsoulteValue(listS5))