将嵌套函数作为C样式和对分解决方案安排到threeSum

时间:2019-03-23 13:15:03

标签: python-3.x

我试图用二进制搜索解决方案解决leetcode中的threeSum问题,并对如何安排内部函数有疑问。

  

给出一个 n 个整数的数组nums,是否存在元素 a b c nums中的 a + b + c = 0?在数组中找到所有零的三元组,它们的总和为零。

     

注意:

     

解决方案集不得包含重复的三胞胎。

     

示例:

     
Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

计划是将ThreeSum分解为twoSum和二分查找

1)首先对nums进行排序,2)声明low_index= 0high_index = len(nums)

修复第一个数字,然后搜索其补语

3)因为num是排序的,所以如果number [1]> 0(目标)中断

4)如果数字重复,则跳过该数字并跳至下一个

5)two_sum搜索number_1'补码,(目标-number_1)


class Solution:
    def threeSum(self, nums, target=0) -> List[List[int]]:
        """
        :type nums: List[int]
        :type target: int 
        :rtype triplets: List[List[int]]
        """
        if len(nums) < 3:
            return []

        nums.sort() #[1]
        triplets = []
        logging.debug(f"Level_1_nums: {nums}\n")  

        lo = 0
        hi = len(nums) #[2]

        while lo < hi -2:   
            if nums[lo] > target:break #[3]
            while 0 < lo < hi -2 and nums[lo] == nums[lo-1]: #[4]
                lo += 1
            number_1 = nums[lo]
            logging.debug(f"number_1: {nums[lo]}")
            logging.debug(f"Level_2_nums: {nums[lo+1:hi]}\n")

            two_sum(nums, target - number_1, lo+1, hi) #[5]    

            lo += 1 #increment 

        return triplets    

6)two_sum内的逻辑与上述相同, 7)binary_search number_2的补码 8)如果找到,请将其附加到triplets

    def two_sum(self, nums, target, lo, hi):
        """
        :type nums: List[int]
        :tppe target: int
        :type triplets:
        :rtype: List[List[int]]
        """

        while lo < hi -1:
            complement = target - nums[lo]

            if self.bi_search(nums, complement, lo+1, hi) != None:

                self.triplets.append([0-target, nums[lo], complement]) 
            lo += 1

            while lo < hi-1 and nums[lo] == nums[lo-1]:
                lo += 1 

9)基本的bi_search函数

    def bi_search(self, a, x, lo=0, hi=None) -> int: #[9]
        if hi == None: 
            hi = len(a)  
        if lo < 0:
            raise ValueError('low must be non-negative')
        while lo < hi: 
            mid = (lo + hi) // 2
            if x == a[mid]: return x
            if x > a[mid]: lo = mid + 1
            if x < a[mid]: hi = mid

将它们放在一起:

from typing import List
import unittest 
import loggiing
import random 
logging.disable(level=logging.CRITICAL)
logging.basicConfig(level=logging.DEBUG, format="%(levelname)s %(message)s")

class Solution:
    """
    Solve the problem by three module funtion
    threeSum
    two_sum
    bi_search 
    """

    def threeSum(self, nums, target=0) -> List[List[int]]:
        """
        :type nums: List[int]
        :type target: int 
        :rtype triplets: List[List[int]]
        inlude two_sum and bi_search function 
        """

        def two_sum(nums, target,lo, hi):
            """
            :type nums: List[int]
            :tppe target: int
            :type triplets:
            :rtype: List[List[int]]
            """
            while lo < hi -1: # [6]
                if nums[lo] > target: break # [6]
                while 0 < lo < hi -1  and nums[lo] == nums[lo-1]: #[6]
                     lo += 1

                number_2 = nums[lo] #[6]
                logging.debug(f"number_2: {nums[lo]}")
                logging.debug(f"Level_3_nums: {nums[lo+1:hi]} \n")

                number_3 = bi_search(nums, target - number_2, lo+1, hi) #[7]
                if number_3 != None: #[8]
                    triplets.append([number_1, number_2, number_3]) #[8]
                    logging.debug(f"triplets: {triplets}")  
                lo += 1


        def bi_search(a, x, lo=0, hi=None): #[9]
            """
            :type a: List[int]
            :type x: int 
            :rtype: value not index 
            """

            if hi == None: 
                hi = len(a)  
            if lo < 0:
                raise ValueError('low must be non-negative')
            while lo < hi: 
                mid = (lo + hi) // 2
                if x == a[mid]: 
                    logging.debug(f"number_3: {x}")
                    return x
                if x > a[mid]: lo = mid + 1
                if x < a[mid]: hi = mid      

#the whole implment block is at the bottom 
        if len(nums) < 3:
            return []

        nums.sort() #[1]
        triplets = []
        logging.debug(f"Level_1_nums: {nums}\n")  

        lo = 0
        hi = len(nums) #[2]

        while lo < hi -2:   
            if nums[lo] > target:break #[3]
            while 0 < lo < hi -2 and nums[lo] == nums[lo-1]: #[4]
                lo += 1
            number_1 = nums[lo]
            logging.debug(f"number_1: {nums[lo]}")
            logging.debug(f"Level_2_nums: {nums[lo+1:hi]}\n")

            two_sum(nums, target - number_1, lo+1, hi) #[5]    

            lo += 1 #increment 

        return triplets    

和TestCase

class TestCase(unittest.TestCase):
    """
    Tesing threeSum.py Solution class.
    """
    def setUp(self):
        self.solution = Solution()

    def test_threeSum(self):
        #nums = [0, 0, 0, 0, 0, 0]
        nums = list(range(-100, 100))
        target = 0
        print(f"\n nums: {nums}\n target: {target}")
        print(self.solution.threeSum(nums, target))

    def test_threeSum_leetcode(self):
        nums = [-1,1,2,-1,0, -8, -7, 0-4, -5, -3]
        #nums = [1,2,-2,-1]
        #nums = [-1,0,1,2,-1,-4]
        # nums = list(range(-100, 100))
        target = 0
        print(f"\n nums: {nums}\n target: {target}")
        print(f"res: {self.solution.threeSum(nums, target)}")        

unittest.main()

我想精细地安排内部功能。因为所有工作代码都位于底部,因此很难阅读。

如何将主要逻辑放在C样式的顶部?

我尽力解决二进制搜索的问题,但仍然超出了时间限制。假定这种体面的解决方案使用leetcodes来使用哈希表。

如果坚持排序和二进制搜索,我又该如何改进代码呢?

0 个答案:

没有答案