• 剑指offer:二分


    题目一

    把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
    输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
    NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
     
    这道题考的是二分法,二分明早再来复盘一下
     
     
     
     
     
     

    错误答案:

    这是我的错误答案,有好几处

    ❤:if...elif...else写成了if...if...else

    ❤:mid的计算方式不对,写成了=right/2,应该是(left+right)作为分子;且式子位置不对,应当写在while里面,因为while里需要用到mid给左右两个值赋值,如果写在外面那么mid就永远不会变了。还有一点就是除法写成//才是向下取整,不然python认为01是浮点数,除出来的结果是浮点型不能作为下标赋值给mid(这个错误经常报)

    ❤:忘记了给while一个终止return

    ❤:while条件不应该写等号

    ❤:还有就是情况考虑不周全,认为下式成立就可以终止条件输出了,其实不是,如果是11101的情况,那么就会输出1而不是0;这种情况只好固定right,让left继续往后走,逐个和固定的right比较,而且因为while left<right才会进行代码块,所以移动过程中是左一直往右和右比较。

    rotateArray[mid]=rotateArray[right]
    class Solution:
        def minNumberInRotateArray(self, rotateArray):
            if len(rotateArray)==0:
                return 0
            if len(rotateArray)==1:
                return rotateArray[0]
            else:
                left=0
                right=len(rotateArray)-1
                mid=right/2
                while left<=right:
                    if rotateArray[mid]<rotateArray[right]:
                        right=mid
                    if rotateArray[mid]>rotateArray[right]:
                        left=mid+1
                    else:
                        return rotateArray[mid]

    所以正确答案如下:

    class Solution:
        def minNumberInRotateArray(self, rotateArray):
            if len(rotateArray)==0:
                return 0
            elif len(rotateArray)==1:
                return rotateArray[0]
            else:
                left=0
                right=len(rotateArray)-1
                while left<right:
                    mid=(left+right)//2
                    if rotateArray[mid]<rotateArray[right]:
                        right=mid
                    elif rotateArray[mid]>rotateArray[right]:
                        left=mid+1
                    else:
                        left+=1
                return rotateArray[left]

     题目二:

    704.给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/binary-search
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    错误答案:

    ❤:做二分涉及到分类的时候不要轻易写else,要多写elif,争取把每种情况都写出来

    ❤:没有理解while下的return,当条件成立时直接输出代码块里的return,当条件不成立时说明没有找到结果,跳出while,输出-1;这题和上题不一样,上题是left和right一起移动,直到两者相等,找到了最小值,跳出代码块,需要输出找到的最小值的结果。

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            if len(nums)==0:
                return -1
            else:
                left=0
                right=len(nums)-1
                while left <= right:
                    mid=(left+right)//2
                    if nums[mid]<target:
                        left=mid+1
                    elif nums[mid]>target:
                        right=mid-1
                    else :
                        return mid
                return mid

    正确答案:

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            if len(nums)==0:
                return -1
            else:
                left=0
                right=len(nums)-1
                while left <= right:
                    mid=(left+right)//2
                    if nums[mid]<target:
                        left=mid+1
                    elif nums[mid]>target:
                        right=mid-1
                    elif nums[mid]==target:
                        return mid
                return -1

     题目三:

    给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

    如果数组中不存在目标值 target,返回 [-1, -1]。

    进阶:

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    说真的下面这个代码跟着别人的代码看了很久,就是没找到为什么自己的代码超出了时间限制。下方为错误答案:

    class Solution:
        def searchRange (self,nums: List[int], target: int) -> List[int]:
            if not nums:
                return [-1,1]
            else:
                return [self._search_left(nums, target), self._search_right(nums, target)]
    
        def _search_left(self, nums: List[int], target: int) -> List[int]:
            left=0
            right=len(nums)-1
            while left <=right:
                mid=(left+(right-left))//2
                if nums[mid]>target:
                    right=mid-1
                elif nums[mid]<target:
                    left=mid+1
                elif nums[mid]==target:#先找左边的边界
                    right=mid-1
            if nums[left]!=target or left >= len(nums):
                return -1
            return left
        
        def _search_right(self, nums: List[int], target: int) -> List[int]:
            left=0
            right=len(nums)-1
            while left <=right:
                mid=(left+(right-left))//2
                if nums[mid]>target:
                    right=mid-1
                elif nums[mid]<target:
                    left=mid+1
                elif nums[mid]==target:#先找右边的边界
                    left=mid+1
            if nums[right]!=target or right< 0:
                return -1
            return right

    终于改出来了:如下

    ❤首先是mid的计算多了括号

    ❤其次题读错了[-1,-1]看成了[-1,1]

    ❤还有就是最后的if判断,应该先判断是否越界再or。不然的话left容易越界导致在数组中读不出,但是right就没关系,反正nums[-1]也能读

    class Solution:
        def searchRange (self,nums: List[int], target: int) -> List[int]:
            if nums==[]:
                return [-1,-1]
            else:
                return [self._search_left(nums, target), self._search_right(nums, target)]
    
        def _search_left(self, nums ,target) :
            left=0
            right=len(nums)-1
            while left <=right:
                mid=left+(right-left)//2
                if nums[mid]>target:
                    right=mid-1
                elif nums[mid]<target:
                    left=mid+1
                elif nums[mid]==target:#先找左边的边界
                    right=mid-1
            if left >= len(nums) or nums[left] != target:
                return -1
            return left
        
        def _search_right(self, nums ,target) :
            left=0
            right=len(nums)-1
            while left <=right:
                mid=left+(right-left)//2
                if nums[mid]>target:
                    right=mid-1
                elif nums[mid]<target:
                    left=mid+1
                elif nums[mid]==target:#先找右边的边界
                    left=mid+1
            if right < 0 or nums[right] != target:
                return -1
            return right

    下面是别人的正确答案:

    class Solution:
        def searchRange(self, nums: List[int], target: int) -> List[int]:
            # 二分查找,搜索左右边界
            if not nums:
                return [-1, -1]
            return [self._search_left(nums, target), self._search_right(nums, target)]
    
        def _search_left(self, nums, target):
            left, right = 0, len(nums) - 1
            while left <= right:
                mid = left + (right - left) // 2
                if nums[mid] > target:
                    right = mid - 1
                elif nums[mid] < target:
                    left = mid + 1
                elif nums[mid] == target:
                    right = mid - 1                         # 改动这里,使搜索区间向左侧收缩
            if left >= len(nums) or nums[left] != target:   # 判断索引越界情况
                return -1
            return left
    
        def _search_right(self, nums, target):
            left, right = 0, len(nums) - 1
            while left <= right:
                mid = left + (right - left) // 2
                if nums[mid] > target:
                    right = mid - 1
                elif nums[mid] < target:
                    left = mid + 1
                elif nums[mid] == target:
                    left = mid + 1                          # 改动这里,使搜索区间向右侧收缩
            if right < 0 or nums[right] != target:          # 判断索引越界情况
                return -1                                   
            return right
    
    作者:jue-qiang-zha-zha
    链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/34-zai-pai-xu-shu-zu-zhong-cha-zhao-yuan-irqc/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    CodeForces 454C——数学——Little Pony and Expected Maximum
    7.23多校——5305DFS——Friends
    Codeforces Round #313 (Div. 2)——C数学题——Gerald's Hexagon
    Codeforces Round #313 (Div. 2)——D递归,stirng——Equivalent Strings
    Codeforces Round #312 (Div. 2)——C暴力技巧——Amr and Chemistry
    简单几何(线段覆盖) POJ 3347 Kadj Squares
    DP+BIT(优化复杂度) UESTC 1217 The Battle of Chibi
    DP(01背包) UESTC 1218 Pick The Sticks (15CCPC C)
    二叉树的前中后序遍历以及表达式树
    DP(优化) UVALive 6073 Math Magic
  • 原文地址:https://www.cnblogs.com/liuxiangyan/p/14418845.html
Copyright © 2020-2023  润新知