leetcode 二分查找&指针解题

leetcode 4.寻找两个有序数组的中位数

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        # 将一个集合划分为两个长度相等的子集,其中一个子集中的元素总是大于另一个子集中的元素
        m, n = len(nums1), len(nums2)
        if m>n: nums1,nums2,m,n = nums2,nums1,n,m
        imin, imax, half_len = 0, m, (m+n+1)/2
        while imin<=imax:
            i = (imin+imax)/2
            j = half_len-i
            if i<m and nums2[j-1]>nums1[i]:
                imin += 1
            elif i>0 and nums1[i-1]>nums2[j]:
                imax -= 1
            else:
                if i==0: max_left = nums2[j-1]
                elif j==0: max_left = nums1[i-1]
                else: max_left = max(nums1[i-1], nums2[j-1])
                if (m+n)%2: return max_left
                if i==m: min_right = nums2[j]
                elif j==n: min_right = nums1[i]
                else: min_right = min(nums1[i], nums2[j])
                return (max_left+min_right)/2.0
# 求解
s=Solution()
s.findMedianSortedArrays([1,3], [2])
# return
2.0

leetcode 9.回文数

class Solution(object):
    def isPalindrome(self, x):
        # 作弊法
        return str(x)==str(x)[::-1]
    
    def isPalindrome(self, x):
        # 指针
        if x<0: return False
        x = str(x)
        n = len(x)
        left, right = 0, n-1
        while left<=right:
            if x[left]==x[right]:
                left += 1
                right -= 1
            else:
                return False
        return True

leetcode 11.盛最多水的容器

class Solution(object):
    def maxArea(self, height):
        n = len(height)
        i, j, maxarea = 0, n-1, 0
        while i>=0 and j<n and i<j:
            left = height[i]
            right = height[j]
            h = min(left, right)
            w = j-i
            maxarea = max(maxarea, h*w)
            if h==left:
                i += 1
            else:
                j -= 1
        return maxarea
# 求解
s = Solution()
s.maxArea([1,8,6,2,5,4,8,3,7])
# return 
49

leetcode 33.搜索旋转排序数组

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

leetcode 34.在排序数组中查找元素的第一个和最后一个位置

class Solution(object):
    def searchRange(self, nums, target):
        if not nums: return [-1, -1]
        n = len(nums)
        left, right = 0, n-1
        if left==right and nums[left]==target: return [left, right]
        while left<right:
            if nums[left]<target: left += 1
            if nums[right]>target: right -= 1
            if nums[left]==nums[right]==target: return [left, right]
        return [-1, -1]

leetcode 35.搜索插入位置

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

leetcode 42.接雨水

class Solution(object):
    def trap(self, height):
        if not height: return 0
        n = len(height)
        left, right, sum = 0, n-1, 0
        max_left = height[left]
        max_right = height[right]
        while left<right:
            max_left = max(height[left], max_left)
            max_right = max(height[right], max_right)
            if max_left<max_right:
                sum += max_left-height[left]
                left += 1
            else:
                sum += max_right-height[right]
                right -= 1
        return sum

74.搜索二维矩阵

class Solution(object):
    def searchMatrix(self, matrix, target):
        # 剔除特殊情况
        if not matrix or not matrix[0]: return False
        if target<matrix[0][0] or target>matrix[-1][-1]: return False
        # 定位到行
        row, col, i = len(matrix), len(matrix[0]), 0
        while i<row and target>matrix[i][-1]: i += 1
        # 二分查找
        left, right = 0, col-1
        while left<right:
            mid = left + (right-left)//2
            if matrix[i][mid]==target:
                return True
            elif matrix[i][mid]<target:
                left = mid+1
            else:
                right = mid
        return True if matrix[i][left]==target else False

leetcode 81.搜索旋转排序数组 II

class Solution(object):
    def search(self, nums, target):
        if not nums: return False
        n = len(nums)
        left, right = 0, n-1
        while left<=right:
            mid = left + (right-left)//2
            if nums[mid]==target:
                return True
            if nums[mid]==nums[left]==nums[right]:
                left += 1
                right -= 1
            elif nums[left]<=nums[mid]:
                if nums[left]<=target<nums[mid]:
                    right = mid - 1
                else:
                    left = mid + 1
            else:
                if nums[mid]<target<=nums[right]:
                    left = mid + 1
                else:
                    right = mid -1
        return False

leetcode 125.验证回文串

class Solution(object):
    def isPalindrome(self, s):
        # 双指针
        n = len(s)
        left, right = 0, n-1
        while left<right:
            while left<right and not s[left].isalnum():
                left += 1
            while left<right and not s[right].isalnum():
                right -= 1
            if s[left].lower() != s[right].lower():
                return False
            left += 1
            right -= 1
        return True

leetcode 153.寻找旋转排序数组中的最小值

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

leetcode 154.寻找旋转排序数组中的最小值 II

class Solution(object):
    def findMin(self, nums):
        if not nums: return
        n = len(nums)
        left, right = 0, n-1
        while left<right:
            while left<right and nums[left]==nums[left+1]: left += 1
            while left<right and nums[right]==nums[right-1]: right -= 1
            mid = left + (right-left)//2
            if nums[mid]>nums[right]:
                left = mid + 1
            else:
                right = mid
        return nums[left]

leetcode 162.寻找峰值

class Solution(object):
    def findPeakElement(self, nums):
        if not nums: return
        n = len(nums)
        left, right = 0, n-1
        while left<right:
            mid = left + (right-left)//2
            if nums[mid]<nums[mid+1]:
                left = mid+1
            else:
                right = mid
        return left

leetcode 167.两数之和 II - 输入有序数组

class Solution(object):
    def twoSum(self, numbers, target):
        if not numbers: return []
        n = len(numbers)
        left, right = 0, n-1
        while left<right:
            total = numbers[left]+numbers[right]
            if total<target:
                left += 1
            elif total>target:
                right -= 1
            else:
                return [left+1, right+1]
        return []

相关推荐