本人算法萌新,为秋招找工作开始磨炼算法,如果我有哪些地方做的有问题的,还请大家不吝赐教.
1.题干
整数数组
nums
按升序排列,数组中的值 互不相同 。在传递给函数之前,
nums
在预先未知的某个下标k
(0 <= k < nums.length
)上进行了 旋转,使数组变为[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]
(下标 从 0 开始 计数)。例如,[0,1,2,4,5,6,7]
在下标3
处经旋转后可能变为[4,5,6,7,0,1,2]
。给你 旋转后 的数组
nums
和一个整数target
,如果nums
中存在这个目标值target
,则返回它的下标,否则返回-1
。你必须设计一个时间复杂度为
O(log n)
的算法解决此问题。示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0 输出:4示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3 输出:-1示例 3:
输入:nums = [1], target = 0 输出:-1提示:
1 <= nums.length <= 5000
-104 <= nums[i] <= 104
nums
中的每个值都 独一无二- 题目数据保证
nums
在预先未知的某个下标上进行了旋转-104 <= target <= 104
2.思考
这道题目的目的是找到一个特定值 target
在数组 nums
中的索引。初始时,可能对题目的理解产生了混淆,误以为需要返回数组排序或反转前的索引。然而,实际上,题目要求的是找到 target
在当前 nums
数组中的确切位置。通过查看示例,明确题目的意图是返回 target
在数组 nums
中的索引值,而不是其他任何转换或操作后的索引,题目限定的时间复杂度为 O(log n)
,所以采用二分查找,但是二分查找要求数组是有序的,所以将数组拆分成两部分来处理,这样能确保有一半肯定是是有序的
3.代码
from typing import List
class Solution:
def search(self, nums: List[int], target: int) -> int:
l, r = 0, len(nums) - 1
while l <= r:
mid = (l + r) >> 1
if nums[mid] == target:
return mid
# 如果左边为有序
if nums[l] <= nums[mid]:
# 如果target在左边
if nums[l] <= target < nums[mid]:
r = mid - 1
else:
l = mid + 1
# 如果左边为无序
else:
# 如果target在右边
if nums[mid] < target <= nums[r]:
l = mid + 1
else:
r = mid - 1
return -1
if __name__ == "__main__":
solution = Solution()
nums = [4, 5, 6, 7, 0, 1, 2]
target = 3
print(solution.search(nums, target))
4.总结
二分查找的时间复杂度为,如遇到基本有序,或部分有序的情况,可以进行迭代拆分处理.