对Backtracking感到困惑?

时间:2018-02-14 09:46:42

标签: python algorithm backtracking

我正在尝试解决此问题Leetcode Question,但我在超出时限的情况下收到错误。

class Solution:  

def readBinaryWatchHelper(self,hours, minutes, num, pastHours, pastMinutes):
    if num == 0:
        hour, minute = sum(pastHours), sum(pastMinutes)
        if self.isValidTime(hour, minute):
            time = str(hour) + ":" + str(minute).zfill(2)
            self.times.add(time)
    else:
        for i in minutes:
            cMinutesTemp = list(minutes)
            pMinutesTemp = list(pastMinutes)
            pMinutesTemp.append(i)
            cMinutesTemp.remove(i)
            if self.isValidTime(sum(pastHours), sum(pMinutesTemp)):
                self.readBinaryWatchHelper(hours, cMinutesTemp, num - 1, pastHours, pMinutesTemp)    
        for i in hours:
            cHoursTemp = list(hours)
            pHoursTemp = list(pastHours)
            pHoursTemp.append(i)
            cHoursTemp.remove(i)
            if self.isValidTime(sum(pHoursTemp), sum(pastMinutes)):
                self.readBinaryWatchHelper(cHoursTemp, minutes, num - 1, pHoursTemp, pastMinutes)


@staticmethod
def isValidTime(hours, minutes):
    if hours < 12 and minutes < 60:
        return True
    return False

def readBinaryWatch(self, num):
    self.times = set()
    hChoices = [1,2,4,8]
    mChoices = [1,2,4,8,16,32]
    self.readBinaryWatchHelper(hChoices[::-1], mChoices[::-1], num, [],[])
    return list(self.times)

这是我使用Backtracking编写的解决方案。我希望我能得到关于为什么它太慢的反馈?其中一个有效的解决方案是获得从0到12的所有小时组合以及从0到60的分钟的所有组合,并检查这些位的总和以查看它们是否加起来是正确的总和。我很困惑这个解决方案比我的更快?由于“修剪树木”,我的不应该更快吗?多谢你们。

1 个答案:

答案 0 :(得分:0)

没有回溯但使用itertools和list comp的解决方案将是:

SELECT *
FROM links l
WHERE NOT EXISTS 
(
    SELECT * 
    FROM works w
    WHERE w.linkId = l.linkId
    AND w.datahora > date_sub(NOW(), INTERVAL 24 HOUR)
) 

测试:

class Solution:
    def readBinaryWatch(self, num):
        """
        :type num: int
        :rtype: List[str]
        """
        from itertools import combinations,  product
        hhmin = min(num,3)+1 # only generate at much as needed
        mmmin = min(num,5)+1 # only generate as much as needed
        nBits = [1,2,4,8,16,32]

        # {0: ['0'], 1: ['1','2','4','8'], 2: ['3','5','9','6','10'], 3: ['7','11']} for>2 
        h = { bitCount: list(str(sum(x)) for x in combinations(nBits,bitCount) 
                          if sum(x) < 12) for bitCount in range(hhmin)}

        m = { bitCount: list(str(sum(x)).zfill(2) for x in combinations(nBits,bitCount) 
                          if sum(x) < 60) for bitCount in range(mmmin)}

        ranges = ((h[subl[0]],m[subl[1]]) for subl in (x for x in product(range(num + 1),
                          range(num + 1)) if sum(x) == num and x[0]<hhmin and x[1]<mmmin))

        return ["{0}:{1}".format(hh,mm) for (hhhh,mmmm) in ranges 
                                        for hh in hhhh for mm in mmmm]

根据不同提交之间的不同,它在55ms到64ms之间拨号。根据该页面,这一比例达到77% - 有一些更短更多的解决方案。提交后,您可以检查其中一些。不幸的是,你的运行根本不运行,递归需要递归,这似乎太慢了。

足够有趣的&#34;蛮力&#34;带有预制列表的s = Solution() for n in range(8): print(s.readBinaryWatch(n)) print() 低于50% - 只需要尝试一下;)

相关问题