分治法学习

经典分治:

215. 数组中的第K个最大元素

题解: 使用快排的思想找第 K 大, 如果当前的下标 pivot == k , 那么我们找到了对应的元素;如果pivot>k ,那么要寻找的元素在pivot左边;如果pivot<k,那么要寻找的元素在pivot右边。

class Solution(object):

    
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """

        def partition(l, r):
            pivot = nums[l]
            while l<r:
                while l<r and nums[r] <= pivot:
                    r-=1
                nums[l] = nums[r]
                while l<r and nums[l] >= pivot:
                    l+=1
                nums[r] = nums[l]
            nums[l] = pivot
            return l
        def find_K(l, r , k):
            if l>r: return
            pivot = partition(l, r)
            if pivot==k: return
            if k < pivot: 
                find_K(l, pivot-1, k)
            else:
                find_K(pivot+1, r, k)
        k-=1
        find_K(0, len(nums)-1, k)
        return nums[k]

 

5484. 找出第 N 个二进制字符串中的第 K 位

分治法: 当前的串为 Sn , 如果n=1, 则返回'0' ; 如果 k == len(Sn)/2 = 1<<(n-1), 那么返回 '1' ; 否则判断k 和 len(Sn)/2的大小,如果 k < len(Sn)/2, 则往左边递归求解; 如果k>len(Sn)/2, 则往右边递归,由于右边的串和左边相反,则第k个变成了第Sn-1中的第 len(Sn) - k 个,如果求解出来答案为0,则返回1,答案为1,则返回0。

class Solution(object):
    def findKthBit(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: str
        """
        if n==1: return '0'
        mid = 2**(n-1)
        if mid==k: return '1'
        if k<mid: return self.findKthBit(n-1, k)
        return '1' if self.findKthBit(n-1, (2**n)-k)=='0' else '0'

 

 

973. 最接近原点的 K 个点

分治法选前K小个元素。

class Solution(object):
    def kClosest(self, points, K):
        """
        :type points: List[List[int]]
        :type K: int
        :rtype: List[List[int]]
        """
        def dist(point):
            return point[0]**2 + point[1]**2
        
        def partition(l, r):
            pivot = dist(points[l])
            idx = points[l]
            while l<r:
                while l<r and dist(points[r]) >= pivot: r-=1
                points[l] = points[r]
                while l<r and dist(points[l]) < pivot: l+=1
                points[r] = points[l]
            points[l] = idx
            return l
        def gettopK(l ,r):
            if l>r: return
            p = partition(l, r)
            if(p==K): return
            elif p>K:
                gettopK(l, p-1)
            else:
                gettopK(p+1,r)
        K-=1
        gettopK(0, len(points)-1)
        K+=1
        return points[:K]

 

 

53. 最大子序和

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        def find(l, r):
            if l>=r: return nums[l]
            m = (l+r)/2
            l_max = find(l, m)
            r_max = find(m+1,r)
            maxl,maxr = -1e9,-1e9
            nowl,nowr = 0,0
            for i in range(m,l-1,-1):
                nowl+=nums[i]
                maxl = max(maxl,nowl)
            for i in range(m+1,r+1):
                nowr+=nums[i]
                maxr = max(maxr,nowr)
            return max(l_max,max(r_max,maxl+maxr))

        return find(0, len(nums)-1)

 

posted @ 2020-08-09 22:04  樱花庄的龙之介大人  阅读(133)  评论(0编辑  收藏  举报