查找最近数问题-Python

189 篇文章 3 订阅

题目描述:

给定一个已排序的整数数组A,和一个待查找的目标值整数target。数组A下标从0开始,元素可能有重复。要求返回数组与target值相等或最相近的元素下标。任何异常情况,返回-1。(编程语言不限,时间复杂度要求为O(logn),同学去云脑科技的面试题)

例如:

A=[1, 2, 3],  target=2,   输出 [1]

A=[1, 4, 6],  target=3,   输出 [1]

A=[1, 4, 6],  target=5,   输出 [1, 2]

A=[1, 3, 3, 4],  target=2,   输出 [0, 1, 2]

问题分析:二分查找最佳位置

Python实现:

# 面试题(同学的)2018-05-24 下午
# 解题思路:二分查找,寻找最佳位置,如果存在返回索引mid,如果不存在返回应该插入的索引mid(保持有序)
# 如果 0 < mid < n:  # 说明找到了或者没找到,但是应该插入数列的内部,从最佳位置向两边查找,找出所有的最近数字
# 如果 mid == 0:  # 小于最左边的数字,只向右查找,找出所有的最近数字
# 如果 mid == n:  # 大于最右边的数字,只向左查找,找出所有的最近数字
# 如果 数组为空 返回 -1


def searchInsert(nums, target):  # 二分查找,如果找到,返回下标索引,没有则返回应该插入的位置(保持有序)
    start = 0
    end = len(nums) - 1
    while start <= end:
        mid = (start + end) // 2
        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            start = mid + 1
        else:
            end = mid - 1
    return end + 1


def rIndex(nums, target):

    n = len(nums)
    if n == 0: return -1
    mid = searchInsert(nums, target)
    rlist = []  # 保持索引
    i, j = -1, n
    left, rigth = 0, 0  # 左右扩展的标志
    mxg = float('-inf')
    if 0 < mid < n:  # 如果找到了
        i, j = mid-1, mid
        mxg = min(abs(nums[i] - target), abs(nums[j] - target))
        left, rigth = 1, 1
    elif mid == 0:  # 小于最左边的数字
        j = mid
        mxg = abs(nums[j] - target)
        left, rigth = 0, 1
    elif mid == n:  # 大于最右边的数字
        i = mid-1
        mxg = abs(nums[i] - target)
        left, rigth = 1, 0

    while left == 1 or rigth == 1:  # 两边查找
        if i == -1: left = 0
        if j == n: rigth = 0
        if left == 1 and i >= 0:
            le = abs(nums[i] - target)
            if le == mxg:
                rlist = [i] + rlist
                i -= 1
            else:
                left = 0
        if rigth == 1 and j < len(nums):
            ri = abs(nums[j] - target)
            if mxg == ri:
                rlist = rlist + [j]
                j += 1
            else:
                rigth = 0
    return rlist


if __name__ == '__main__':
    nums, target = [1, 1, 2, 2, 4, 4], 3
    print(rIndex(nums, target))

发现问题,请评论指正哦

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值