问题描述
问题如下:
我们的输入是一个包含 14 个数字的数组,我们的输出是这手牌是否是赢牌。 要使一手牌成为赢手,必须可以按照以下规则将其数字分组:
- 每组 3 个必须是相同的数字或顺子(111 或 123)
- 我们只能有一对相同的数字(22 可以,但 45 不行)
例如:
[1,1,2,3,4,5,5]: True
[1,6]: False
[1,6,8,8]: True
我使用回溯技术为问题编写了以下解决方案:
注意:忽略所有出现的 seen
它是我下面问题第二部分的记忆的一部分。
def is_winning_hand(hand):
hand.sort()
seen = set()
return is_winning_hand_step(hand,True,seen)
def is_winning_hand_step(hand,can_take_two,seen):
if len(hand) == 0:
return True
if len(hand) == 1:
return False
if str(hand)+str(can_take_two) in seen:
return False
if can_take_two:
valid,new_hand = take_two(hand)
if valid:
if is_winning_hand_step(new_hand,False,seen):
return True
if len(hand) >= 3:
valid,new_hand = take_three(hand)
if valid:
if is_winning_hand_step(new_hand,seen):
return True
valid,new_hand = take_straight(hand)
if valid:
if is_winning_hand_step(new_hand,seen):
return True
seen.add(str(new_hand)+str(can_take_two))
return False
def take_two(hand):
if hand[0] == hand[1]:
return True,hand[2:]
else:
return False,None
def take_three(hand):
if hand[0] == hand[1] and hand[1] == hand[2]:
return True,hand[3:]
else:
return False,None
def take_straight(hand):
cnt = 1
last_val = hand[0]
indices = set([0])
for i in xrange(1,len(hand)):
if hand[i] == last_val:
continue
elif hand[i] == last_val + 1:
cnt += 1
indices.add(i)
last_val = hand[i]
if cnt == 3:
return True,[x for j,x in enumerate(hand) if j not in indices]
else:
return False,None
return False,None
现在我试图找出该问题的时间复杂度是多少。
让我们假设输入已经为我们排序,所以将它的 O(N log N)
放在一边。
我的猜测是,因为在每一步中,我都有可能分成 3 个分支,所以复杂度是 O(3^N)
,其中 N 应该是输入数组的长度。在我们的例子中,它总是 14 个长度的数组,但我说的是一般情况。我说的对吗?
在下一步中,我在我的解决方案中添加了记忆。关于时间复杂度,我们现在能说什么?多亏了记忆,我避免了一次又一次地解决相同的子问题,所以这使它成为 O(N)
解决方案吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)