算法—day1
Posted Mrs.King_UP
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法—day1相关的知识,希望对你有一定的参考价值。
二分查找
question 1:
题目描述:给定一个
n
n
n 个元素有序的(升序)整型数组
n
u
m
s
nums
nums 和一个目标值
t
a
r
g
e
t
target
target ,写一个函数搜索
n
u
m
s
nums
nums 中的
t
a
r
g
e
t
target
target,如果目标值存在返回下标,否则返回 -1。
示例1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
解答:
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
low=0
high=len(nums)-1
while low<=high:
mid=(low+high)//2
if nums[mid]<target:
low=mid+1
elif nums[mid]>target:
high=mid-1
else:
return mid
return -1
解答二分查找的题目的疏忽在于:
-
m
i
d
mid
mid为整数,所以使用整除符号
//
- n u m s nums nums列表中只有一个元素时,且等于 t a r g e t target target时,此时 l o w = h i g h = 0 low=high=0 low=high=0,所以while循环的判定条件为 l o w < = h i g h low<=high low<=high
question 2:
题目描述:你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例1:
输入:n = 5, bad = 4
输出:4
解释:
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
示例2:
输入:n = 1, bad = 1
输出:1
解答:
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return a bool
# def isBadVersion(version):
class Solution(object):
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
# for i in range(1,n+1):
# if isBadVersion(i):
# return i
low=1
high=n
while low<=high:
mid=(low+high)//2
if isBadVersion(mid):
if isBadVersion(mid-1):
high=mid-1
else:
return mid
elif isBadVersion(mid)==False:
low=mid+1
return -1
解答此题目的疏忽在于:
- 读题不仔细:题目描述中提到要尽量的减少对isBadVersion(version) 接口的调用,如果使用for循环,直接调用该接口bad次,时间复杂度为 O ( n ) O(n) O(n),所以使用二分查找 O ( l o g n ) O(logn) O(logn)。
- 当且仅当isBadVersion(mid)==1且isBadVersion(mid-1)==0时,此时mid为第一个出现错误的版本,找到满足这样要求的mid。
question 3:
题目描述:给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例3:
输入: nums = [1,3,5,6], target = 7
输出: 4
示例4:
输入: nums = [1,3,5,6], target = 0
输出: 0
示例5:
输入: nums = [1], target = 0
输出: 0
解答:
class Solution(object):
def searchInsert(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
low=0
high=len(nums)-1
while low<=high:
mid=(low+high)//2
if nums[mid]>target:
high=mid-1
elif nums[mid]<target:
low=mid+1
else:
return mid
return low
解答该题目要注意:
- 明确两点:target在列表中,返回索引;target不在列表中,返回插入位置
- 二分查找是用来找到target在列表中的位置,若target不在列表中,则会退出while循环,执行查找插入位置部分,通过分析实例2、3、4,在退出while循环时,指针low所指的位置为target的插入位置,所以退出while循环表示target不在列表中,此时的返回值应为low。
以上是关于算法—day1的主要内容,如果未能解决你的问题,请参考以下文章