2021-08-03leetcode刷题

2021-08-03  本文已影响0人  Cipolee

编写一个高效的算法来判断 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
上一篇 下一篇

猜你喜欢

热点阅读