一、题目描述
已知存在一个按非降序排列的整数数组 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,4,4,5,6,6,7]
在下标 5
处经旋转后可能变为 [4,5,6,6,7,0,1,2,4,4]
。
给你 旋转后 的数组 nums
和一个整数 target
,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 nums
中存在这个目标值 target
,则返回 true
,否则返回 false
。
你必须尽可能减少整个操作步骤。
示例 1
输入:nums = [2,5,6,0,0,1,2], target = 0
输出:true
示例 2
输入:nums = [2,5,6,0,0,1,2], target = 3
输出:false
提示:
1 <= nums.length <= 5000
-10^4 <= nums[i] <= 10^4
题目数据保证 nums 在预先未知的某个下标上进行了旋转
-10^4 <= target <= 10^4
二、代码
代码如下:
class Solution:
def search(self, nums: List[int], target: int) -> bool:
nums = list(set(nums))
l = 0
r = len(nums)-1
while l <= r:
m = int((l + r) / 2)
if nums[l] == target or nums[r] == target:
print("True")
return True
if target == nums[m]:
print("True")
return True
# 如果左边部分有序:
if nums[0] <= nums[m]:
# 如果目标值在左边部分范围
if nums[0] <= target < nums[m]:
# 缩小左边部分的右边界
r = m - 1
# 如果目标值超出了左边部分范围
else:
# 跳转至右边部分
l = m + 1
# 如果右边部分有序(至少有一边是有序的):
else:
# 如果目标值在右边部分范围内
if nums[m] < target <= nums[len(nums) - 1]:
# 缩小右边部分的左边界
l = m + 1
# 如果目标值超出了右边部分范围
else:
# 跳转至左边界
r = m - 1
print("False")
# 如果最后仍然没有找到目标值,则返回-1
return False
三、解题思路
本题是33. 搜索旋转排序数组 Python的加强版,多出了“数组中的值不必互不相同”这一条件,这使得原本33.搜索旋转排序数组中的题解并不能满足所有的题目(例如:[1,1,1,1,0,1,1]
或者[1,0,1,1,1,1]
),因为按照之前的题中必定满足中心坐标m的左右两侧必定有一侧是有序的;但对于本题来说,由于存在相同的数值,会导致之前的算法无法准确判断左右两侧哪一侧是有序的,所以不能准确找出目标值。
本题题解的思路很简单,既然此时的nums
无法满足33. 搜索旋转排序数组 Python的输入要求,那就将修改nums
使其中不含重复元素,用set()
方法可以快速得到没有重复元素的数组(注意需要转换成list格式),之后再将转化好的数组nums用33.搜索旋转排序数组的解题思路求解即可。