算法—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

解答二分查找的题目的疏忽在于:

  1. m i d mid mid为整数,所以使用整除符号//
  2. 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
        


解答此题目的疏忽在于:

  1. 读题不仔细:题目描述中提到要尽量的减少对isBadVersion(version) 接口的调用,如果使用for循环,直接调用该接口bad次,时间复杂度为 O ( n ) O(n) O(n),所以使用二分查找 O ( l o g n ) O(logn) O(logn)
  2. 当且仅当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

解答该题目要注意:

  1. 明确两点:target在列表中,返回索引;target不在列表中,返回插入位置
  2. 二分查找是用来找到target在列表中的位置,若target不在列表中,则会退出while循环,执行查找插入位置部分,通过分析实例2、3、4,在退出while循环时,指针low所指的位置为target的插入位置,所以退出while循环表示target不在列表中,此时的返回值应为low。

以上是关于算法—day1的主要内容,如果未能解决你的问题,请参考以下文章

算法—day1

算法—day1

每日一面day1

算法竞赛入门经典——读书笔记day1

2021年SWPUACM暑假集训day1二分算法

备战蓝桥 算法·每日一题(详解+多解)-- day1