问题1 搜索插入位置
给定一个排序数组和一个目标值,如果在数组中找到目标值则返回索引。如果没有,返回到它将会被按顺序插入的位置。
你可以假设在数组中无重复元素。
样例
[1,3,5,6],5 → 2
[1,3,5,6],2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6],0 → 0
挑战
O(log(n)) time
def searchInsert(self, A, target):
# write your code here
n=len(A)
if(n==0):
return 0
left,right=0,n-1
while(right>left and (right-left)!=1):
mid=left+((right-left)>>1)
if(A[mid]>target):
right=mid
elif(A[mid]<target):
left=mid
else:
return mid
if(target<=A[left]):
return left
elif(A[right]<target):
return right+1
else:
return right
思路:
要求O(log(n)) time,显示是二分法求解,一步步找出target在数组中的位置,当只剩下left和right两个元素时候,比较他们与target的关系,即可以找到要插入的位置。
问题2 搜索旋转排序数组
假设有一个排序的按未知的旋转轴旋转的数组(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2)。给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。
你可以假设数组中不存在重复的元素。
样例
给出[4, 5, 1, 2, 3]和target=1,返回 2
给出[4, 5, 1, 2, 3]和target=0,返回 -1
挑战
O(logN) time
def searchInsert(self, A, target):
# write your code here
n=len(A)
if(n==0):
return 0
left,right=0,n-1
while((right-left)>1):
mid=left+((right-left)>>1)
if(A[mid]>target):
right=mid
elif(A[mid]<target):
left=mid
else:
return mid
if(target==A[left]):
return left
elif(A[right]==target):
return right
else:
return -1
def search(self, A, target):
# write your code here
n=len(A)
if n==0:
return -1
location=-1
for i in range(n-1):
if(A[i+1]-A[i]<0):
location=i
if location==-1:
return Solution.searchInsert(self=self,A=A,target=target)
else:
arrRight=A[(location+1):]
arrLeft=A[:(location+1)]
print('loc',location)
if(target<=A[n-1]):
indRight=Solution.searchInsert(self=self,A=arrRight,target=target)
print('indRight',indRight)
return location+1+indRight if indRight!=-1 else -1
elif(target>=A[0]):
indLeft=Solution.searchInsert(self=self,A=arrLeft,target=target)
print('indLeft',indLeft)
return indLeft if indLeft!=-1 else -1
else:
return -1
思路:
与之前的问题有一点不同的是,这里如果数组中不存在target则返回-1;
先找旋转数组中的boundary(也要考虑到这个数组没有boundary,就是一个顺序数组的情况)。
找到boundary之后,将数组分成两个小数组,然后分别应用搜索插入位置的算法即可。对于右边数组,在得到插入位置之后,还需要加一个boundary大小。