美文网首页
2021-08-03leetcode刷题

2021-08-03leetcode刷题

作者: Cipolee | 来源:发表于2021-08-03 16:56 被阅读0次

    编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:每行中的整数从左到右按升序排列。
    每行的第一个整数大于前一行的最后一个整数。

    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
            m,n=len(matrix),len(matrix[0])
            m_l,m_r=0,m-1
            n_l,n_r=0,n-1
            #m_m=0
            while m_l<m_r:
                m_m=(m_l+m_r)//2
                if matrix[m_m][-1]==target:
                    return True
                elif matrix[m_m][-1]<target:
                    m_l=m_m+1
                else:
                    m_r=m_m
            while n_l<n_r:
                n_m=(n_l+n_r)//2
                if matrix[m_l][n_m]==target:
                    return True
                elif matrix[m_l][n_m]<target:
                    n_l=n_m+1
                else:
                    n_r=n_m-1
            return True if matrix[m_l][n_l]==target else False
    
    image.png

    下面的题与标解相差较大

    整数数组 nums 按升序排列,数组中的值 互不相同 。
    在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
    给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

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

    标解

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            if not nums:
                return -1
            l, r = 0, len(nums) - 1
            while l <= r:
                mid = (l + r) // 2
                if nums[mid] == target:
                    return mid
                if nums[0] <= nums[mid]:
                    if nums[0] <= target < nums[mid]:
                        r = mid - 1
                    else:
                        l = mid + 1
                else:
                    if nums[mid] < target <= nums[len(nums) - 1]:
                        l = mid + 1
                    else:
                        r = mid - 1
            return -1
    
    作者:LeetCode-Solution
    链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-
    array/solution/sou-suo-xuan-zhuan-pai-xu-shu-zu-by-leetcode-solut/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    对深入理解二分有帮助

    给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
    如果数组中不存在目标值 target,返回 [-1, -1]。

    class Solution:
        def searchRange(self, nums: List[int], target: int) -> List[int]:
            if len(nums)==0:
                return [-1,-1]
            left,right=0,len(nums)-1
            for i in range(2):
                tl,tr=0,right
                while tl<tr:
                    mid=(tl+tr)//2 if i==0 else (tl+tr+1)//2
                    #mid=(tl+tr)//2
                    if nums[mid]==target:
                        if i==0:
                            #print('0 {}'.format(mid))
                            tr=mid
                        else:
                            #print('1 {}'.format(mid))
                            tl=mid
                    elif nums[mid]>target:
                        tr=mid-1
                    else:
                        tl=mid+1
                    
                if i==0:
                    left=tl
                else:
                    #print("hi")
                    right=tr 
            return [left,right] if nums[left]==target else [-1,-1]
    

    关于优化时间复杂度和空间复杂度的想法

    class Solution:
        def minCostClimbingStairs(self, cost: List[int]) -> int:
            #cost.append(0)
            #ans,n=cost[:2],len(cost)
            a,b=cost[:2]
            n=len(cost)
            for i in cost[2:]:
                a,b=b,min(a,b)+i
            return min(a,b)
    
    
    
    image.png

    已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
    若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
    若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]
    注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
    给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。

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

    相关文章

      网友评论

          本文标题:2021-08-03leetcode刷题

          本文链接:https://www.haomeiwen.com/subject/lpssvltx.html