美文网首页
75. Sort Colors | 88. Merge Sort

75. Sort Colors | 88. Merge Sort

作者: 4v3r9 | 来源:发表于2019-01-16 16:31 被阅读3次

75. Sort Colors

题目要求见: https://leetcode.com/problems/sort-colors/

方法一

two-pass方法,先遍历一遍,记下0, 1, 2元素的数目;再遍历一遍,分别将这些数目的0, 1, 2覆盖nums.

时间复杂度:O(n)
空间复杂度:O(1)

class Solution(object):
    def sortColors(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        
        #method1
        if not nums:
            return 
        count = [0,0,0]
        for ele in nums:
            if ele == 0:
                count[0]+=1
            elif ele == 1:
                count[1] +=1
            elif ele ==2:
                count[2] +=1
            else:
                return 
        p = 0
        while count[0]>0:
            nums[p] = 0
            p+=1
            count[0] -=1
            
        while count[1] > 0:
            nums[p] = 1
            p += 1
            count[1] -= 1

        while count[2] > 0:
            nums[p] = 2
            p += 1
            count[2] -= 1

方法二

维护三个指针,p0, p1, p2.

  • p0: [0, p0] 为0
  • p1: (p0, p1] 为1
  • p2: [p2, n) 为2

时间复杂度:O(n)
空间复杂度:O(1)

class Solution(object):
    def sortColors(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        
        #method2
        if not nums:
            return 
        n = len(nums)
        p0 = -1 #[0, p0]
        p1 = 0 # start from 0, meaning (p0, p1] is 1
        p2 = n # [p2, n) is 2

        while p1 < p2:
            if nums[p1] ==1:
                p1+=1
            elif nums[p1] ==0:
                p0+=1
                temp = nums[p1]
                nums[p1] = nums[p0]
                nums[p0] = temp
                p1 +=1
            elif nums[p1] ==2:
                #swap
                p2 -=1
                nums[p1], nums[p2] = nums[p2], nums[p1]

88. Merge Sorted Array

题目要求见: https://leetcode.com/problems/merge-sorted-array/

如果nums2为空,直接返回nums1;如果nums2都比nums1大,直接整体移到nums1后面;如果nums2都比nums1小,把nums1整体后移,再把nums2整体拼接到nums1前面.
如果nums1, nums2范围有交集,就维持两个指针指向nums1, nums2的尾部,每次把更大的值赋值给nums1尾部,然后该值的指针前移.
如果最后剩下了nums2的指针,就直接把剩下部分的数拼接到nums1的头部.

时间复杂度:O(n)
空间复杂度:O(1)

class Solution(object):
    def merge(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: void Do not return anything, modify nums1 in-place instead.
        """
        if not nums2:
            return

        if nums1 and nums2:

            if nums2[0] >= nums1[m-1]:
                nums1[m:m+n] = nums2[:]
            elif nums2[-1] <= nums1[0]:
                nums1[n:n+m] = nums1[:m]
                nums1[:n] = nums2[:]
            else:
                p1, p2 = m, n
                while m and n:
                    if nums2[n-1] >= nums1[m-1]:
                        nums1[m+n-1] = nums2[n-1]
                        n -=1
                    else:
                        nums1[m+n-1] = nums1[m-1]
                        m -=1
                if n:
                    nums1[:n] = nums2[:n]

这里有一个Python的陷阱:当n变成0的时候,再循环下去就是 -1,于是从nums2第一个元素指向了nums2最后一个元素.所以必须要以0为边界条件,然后再另加判断.

215. Kth Largest Element in an Array

题目要求见: https://leetcode.com/problems/kth-largest-element-in-an-array/

方法一

最傻的办法是 快速排序+切片取第k个值.这里手动实现快速排序作为练习.

时间复杂度:O(nlogn)
空间复杂度:O(1)

class Solution(object):
    def findKthLargest(self, nums, k):
        def quicksort(array,low,high):
            ''' realize from book "data struct" of author 严蔚敏
            '''
            if low < high:
                key_index = partion(array,low,high)
                quicksort(array,low,key_index)
                quicksort(array,key_index+1,high)

        def partion(array,low,high):
            key = array[low]
            while low < high:
                while low < high and array[high] >= key:
                    high -= 1
                if low < high:
                    array[low] = array[high]

                while low < high and array[low] < key:
                    low += 1
                if low < high:
                    array[high] = array[low]

            array[low] = key
            return low
        
        if not nums:
            return 
        n = len(nums)
        quicksort(nums, 0, n-1)
        
        return nums[-k]
            

方法二 改良的快速排序

快速排序是递归地在一个范围内选取pivot,然后把小于pivot的数移到其左边,大于pivot的数移到其右边,然后再对左右两个更小的范围进行排序.
因为每次排序完后,pivot的位置刚好对应其排序的位置,所以可利用这点决定目标是在左边子范围还是在右边子范围,从而把时间复杂度缩小.

时间复杂度:O(n)
空间复杂度:O(1)

class Solution:
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        def partition(left, right, pivot_index):
            pivot = nums[pivot_index]
            # 1. move pivot to end
            nums[pivot_index], nums[right] = nums[right], nums[pivot_index]  
            
            # 2. move all smaller elements to the left
            store_index = left
            for i in range(left, right):
                if nums[i] < pivot:
                    nums[store_index], nums[i] = nums[i], nums[store_index]
                    store_index += 1

            # 3. move pivot to its final place
            nums[right], nums[store_index] = nums[store_index], nums[right]  
            
            return store_index
        
        def select(left, right, k_smallest):
            """
            Returns the k-th smallest element of list within left..right
            """
            if left == right:       # If the list contains only one element,
                return nums[left]   # return that element
            
            # select a random pivot_index between 
            pivot_index = random.randint(left, right)     
                            
            # find the pivot position in a sorted list   
            pivot_index = partition(left, right, pivot_index)
            
            # the pivot is in its final sorted position
            if k_smallest == pivot_index:
                 return nums[k_smallest]
            # go left
            elif k_smallest < pivot_index:
                return select(left, pivot_index - 1, k_smallest)
            # go right
            else:
                return select(pivot_index + 1, right, k_smallest)

        # kth largest is (n - k)th smallest 
        return select(0, len(nums) - 1, len(nums) - k)

相关文章

网友评论

      本文标题:75. Sort Colors | 88. Merge Sort

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