Algorithm Facebook HackerCup 2013年余额表说明

Algorithm Facebook HackerCup 2013年余额表说明,algorithm,Algorithm,我的问题是关于FB HackerCup 2013资格赛轮次问题-平衡问题 问题陈述:(也复制到这里:) 我想出了如何使用BruteForce方法解决这个问题,该方法具有指数级的运行时间 根据发布的官方解决方案,有一个线性运行时间的解决方案。这里描述的是: 本质上,它维护两个计数器:minOpen和maxOpen。每当遇到一个开括号“(”时,maxOpen将递增。如果“(”不是笑脸的一部分,minOpen也将递增。类似的处理策略”)”,如上面的解释链接所述 我可以看出线性时间方法是有效的,但我的头

我的问题是关于FB HackerCup 2013资格赛轮次问题-平衡问题

问题陈述:(也复制到这里:)

我想出了如何使用BruteForce方法解决这个问题,该方法具有指数级的运行时间

根据发布的官方解决方案,有一个线性运行时间的解决方案。这里描述的是:

本质上,它维护两个计数器:minOpen和maxOpen。每当遇到一个开括号“(”时,maxOpen将递增。如果“(”不是笑脸的一部分,minOpen也将递增。类似的处理策略”)”,如上面的解释链接所述

我可以看出线性时间方法是有效的,但我的头脑中还不十分清楚-怎么做?所以我正在调查这个小组,看看是否有人可以对线性运行时间解决方案给出另一种“解释”


非常感谢!

预处理:标记化输入,并将每个标记转换为一个列表,其中包含对开括号计数可能产生的影响

输入

i am sick today (:()
:(:))
变成

[[0], [0], ..., [0], [1], [0, 1], [-1]]
[[0, 1], [-1, 0], [-1]]
.现在,你的暴力算法是这样的

def solution1(lst, opencnt=0, i=0):
    if opencnt < 0:
        return False
    elif i >= len(lst):
        return opencnt == 0
    else:
        for delta in lst[i]:
            if solution1(lst, opencnt + delta, i + 1):
                return True
        return False

这个实现还不是线性时间。最后的优化是
opencnt
始终是一个间隔,即[minOpen,maxOpen],并且可以在恒定时间内进行操作。

如果不是规则#2中的冒号,显而易见的算法将是一个具有两个状态的有限状态机,它在字符串上循环并保持括号计数:

  • pcount=0
  • 对于每个字符:
    • 如果是“:”:放弃下一个字符
    • 如果是“(”:
      pcount++
    • 如果是“'):
      pcount--
      if
      pcount>0
      ,否则立即返回“否”
规则#2允许冒号这一事实使它更具挑战性,因为形式为“(:)”或(foo:)”的消息也可能被视为具有平衡的括号。该规则本质上说的是“你发现很难判断括号是否真的是括号或表情符号的一部分”,你应该确定“有一种方法可以在保持括号平衡的同时解释他的信息”

更清楚地说:我们实际上根本不在乎表情符号。我们将看看括号是否平衡

最简单的方法是维护一个括号计数器数组。最初,它只包含一个括号计数器。每次遇到“(”或“),将当前圆括号计数器数组附加到自身,按照上面简单算法中的建议,在前半部分进行-/递减。到达字符串末尾后,检查数组是否包含零。如果包含零,则有一种方法可以将字符串视为具有平衡圆括号。否则,不存在平衡圆括号


第二个算法可能还有改进的余地,甚至可能有一个令人瞠目结舌的优雅解决方案,如果消息由1000个括号组成,它不会耗尽内存。但是,如果有足够的RAM,这种天真的方法将在线性时间(遗憾的是,指数空间)内确定正确答案.

你必须有相等数量的开括号和闭括号。你不计算微笑中的括号。除此之外,没有什么其他的。仅仅有相等数量的开括号和闭括号是不够的。它们必须按正确的顺序排列。此外,我不认为说微笑中的括号不被计算是真的。如果没有简单的解释,它们是不被计算的括号来平衡另一个问题。这就是为什么要对minOpen和maxOpen进行评估。我应该更仔细地阅读您的问题。我将留下我的答案,以提醒其他人。
def solution2(lst, opencnt={0}, i=0):
    opencnt = {x for x in opencnt if x >= 0}
    if i >= len(lst):
        return 0 in opencnt
    else:
        return solution2(lst, {x + delta for x in opencnt for delta in lst[i]}, i + 1)