微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

可能具有最佳时间复杂度的字母汤问题

如何解决可能具有最佳时间复杂度的字母汤问题

我在数据结构课程练习中遇到了以下问题(字母汤)。

https://github.com/kennedyCzar/AlphabetSoup-Using-Django

我在 O(m+s) 中解决了它,其中 m 是消息的长度,s 是汤的长度(我刚刚从汤中创建了一个表,并决定是否可以使用它来创建消息表)

def checkBowl(message,soup):
  d = {}

  # O(S)
  for c in soup:
    d[c] = d.get(c,0) + 1

  # O(m)
  for c in message:
    if(d.get(c,0) == 0):
      return False
    else:
      d[c] -= 1

  # So the overall time complexity is O(m+s)
  return True

但似乎给定的 GitHub 在 O(mlogm) 中解决了它,但是我认为他/她的解决方案是在 O(m*s) 中,因为他/她只是没有考虑 Python 的操作符在 O(长度的列表)。

顺便说一下,有人可以提示一下,是否有可能以更好的时间复杂度解决这个问题? (问题说明这碗汤可能很大)

解决方法

正如您所说,链接算法对于消息中的每个字母,都会遍历整个汤以找到该字母。如果找到该字母,则将其从汤中取出。因此时间复杂度为 O(m * S)

您的算法是 O(m + S),因为您只对汤进行了一次迭代。所以你的解决方案更好。

但是如果汤很大怎么办?无限汤呢?如果汤是一个无限生成器,即使汤的第一个字母是消息本身,您也永远无法完成字典的构建。

这引出了一个想法:为什么不在得到消息的字母之前迭代汤的字母?在这种情况下,您将阅读信件,直到您能够撰写邮件并在邮件完成后立即停止:

import collections

def check_bowl2(message,soup):
    # O(m)
    message_letters = collections.Counter(message)

    # O(S)
    for c in soup:
        if c not in message_letters: # we don't need `c`
            pass
        elif message_letters[c] == 1:
            del message_letters[c] # we won't need `c` anymore
            if not message_letters: # we found all letters
                return True
        else: # we still need `c`,but one less time
            message_letters[c] -= 1

    return False

时间复杂度仍然是O(m + S),但空间复杂度降低了:O(m) vs O(S)。当然,如果你在同一个汤里寻找很多消息,构建 dict 仍然是最好的选择。

我认为您找不到比 O(S) 更快的算法:在最坏的情况下(没有消息),您必须至少遍历整个汤一次。

,

我不认为你可以解决这个问题,因为如果不解析一个字母就不可能检查它是否属于字母汤,而且你显然必须解析你的消息。

但是,您的解决方案仅在 AVERAGE 上是线性的,因为哈希映射仅平均具有恒定的复杂性。所以你最坏情况的复杂度更像是 O(s^2+s.m)。

你可以使用你自己的数据结构来改进它,例如,不依赖于哈希而是二叉树,以实现 O(s.log(s)+ m.log(s)) 的最坏情况复杂度。>

编辑:您也可以利用您的字符只是 ASCII 字符这一事实。

def checkBowl(message,soup):                                                                                                                                                                            
  d = [0 for i in range(128)]
              
  # O(S)      
  for c in soup:
    d[ord(c)] +=1
              
  # O(m)      
  for c in message:
    if(d[ord(c)] == 0):
      return False
    else:     
      d[ord(c)] -= 1
               
  # So the overall time complexity is O(m+s)
  return True 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。