给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
首先做这道题先回忆下基础用法
Python list内置sort()方法用来排序,也可以用python内置的全局sorted
()方法来对可迭代的序列排序生成新的序列
1)排序基础
简单的升序排序是非常容易的,只需要调用sorted()方法,它返回一个新
的list,新的list的元素基于小于运算符(__lt__)来排序
a=[7,8,5,3,9,0,6]
print(sorted(a)) #[0, 3, 5, 6, 7, 8, 9]
也可以使用list.sort()方法来排序,此时list本身将被修改,通常此方法不如sorted()方便,但是如果你不需要保留原来的list,此方法将更有效
a=[7,8,5,3,9,0,6]
a.sort()
print(a) #[0, 3, 5, 6, 7, 8, 9]
2)列表添加数据基础,append()、extend()、insert()方法的区别
1、append()方法是在列表末尾增加一个数据项
students = ['Cleese' , 'Palin']
students.append('Jones')
print(students)#['Cleese', 'Palin', 'Jones']
2、extend()方法是指在列表末尾增加一个数据集合,两个数组相加
a=[1,2,3]
students = ['Cleese' , 'Palin']
students.append('Jones')
students.extend(a)
print(students)#['Cleese', 'Palin', 'Jones', 1, 2, 3]
3、insert()方法是指在某个特定位置前面增加一个数据项
students = ['Cleese' , 'Palin']
students.insert(1,2)
print(students)#['Cleese', 2, 'Palin']
3) 获取列表的下标
students = ['Cleese' , 'Palin']
print(students.index('Palin'))#1
4) list[-1]表示列表的最后一个值
1、解题1我使用的笨拙的方法
注意
这个我理解是都要先排序
前提是先排序升序了
1、nums为空的时候
2、目标值在nums时
3、目标小于nums[0]时
4、目标值大于nums[-1]时
5、目标值在大于nums[n],小于num[n+1]时
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
asset_nums = sorted(nums)
if len(asset_nums) == 0 or target < nums[0]:
nums.insert(0, target)
return 0
if target in nums:
index = nums.index(target)
return index
elif target > asset_nums[-1]:
asset_nums.append(target)
return asset_nums.index(target)
else:
for i in range(len(asset_nums) - 1):
if asset_nums[i] < target < asset_nums[i + 1]:
asset_nums.insert(i + 1, target)
return i + 1
2、看了大佬们解法
1、不管值在没在nums里面都先添加
2、排序
3、获取target的index
class Solution1:
def searchInsert(self, nums: List[int], target: int) -> int:
nums.append(target)
nums.sort()
return nums.index(target)
3、使用二分法
数据没有做升序的排序
mid=(left+right)/2会先计算left+right,left+right比right大,是有可能溢出的
,和数据类型关系不大,虽然可以定义成位数更高的数据类型防止溢出,但是一旦
超过程序语言的上限值,还是得用mid = left + (right - left) / 2
,有人可能觉得mid=(left+right)/2把括号打开一样能防止溢出,为啥不用呢?因
为mid=left/2+right/2使用了两次除法一次加法,相比之下mid = left + (right - left) / 2使用了两次加法一次除法,乘除法的代价更高,所以mid = left + (right - left) / 2 的形式更优。
class Solution:
def searchInsert(self, nums, target: int) -> int:
left,right=0,len(nums)
while left<right:
mid=left+(right-left)//2 #整除
if nums[mid]<target:
left = mid+1
else:
right = mid
return left