📣 独立日限时特惠: VIP通行证立减$68
查看: 2254| 回复: 8
跳转到指定楼层
上一主题 下一主题
收起左侧

Leetcode 336 求教 感觉写了O(n) 可是TLE了

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
  1. class Node:
  2.     def __init__(self,digit):
  3.         self.char = digit
  4.         self.children = {}
  5.         self.isword = False
  6.         self.wordidx = None
  7.         self.word = None
  8.         self.palinidx = []
  9. class Trie:
  10.     def __init__(self):
  11.         self.head = Node("")
  12.         self.palindrone = []
  13.     def insert(self,word,idx):
  14.         if word == "":
  15.             self.head.isword = True
  16.             self.head.wordidx = idx
  17.             self.head.word = ""
  18.             return
  19.         tmp = self.head
  20.         if self.isplin(word):
  21.             tmp.palinidx.append(idx)
  22.         for i in range(len(word)):
  23.             if word[i] not in tmp.children:
  24.                 tmp.children[word[i]] = Node(word[i])
  25.             if self.isplin(word[i::]):
  26.                 #print(word,word[(i+1)::])
  27.                 tmp.palinidx.append(idx)
  28.                 #print(tmp.word,tmp.char,tmp.palinidx)
  29.             tmp = tmp.children[word[i]]
  30.         tmp.isword = True
  31.         tmp.wordidx = idx
  32.         tmp.word = word
  33.         if self.isplin(word):
  34.             self.palindrone.append(idx)
  35.             
  36.     def find(self,word):
  37.         if word == "":
  38.             return self.palindrone
  39.         tmp = self.head
  40.         ans = []
  41.         if tmp.isword and self.isplin(word):
  42.             ans.append(tmp.wordidx)
  43.         for i in range(1,len(word) +1):
  44.             if word[-i] in tmp.children:
  45.                 tmp = tmp.children[word[-i]]
  46.                 if tmp.isword:
  47.                     if self.isplin(word[-len(word):(-i)]):
  48.                         ans.append(tmp.wordidx)
  49.             else:
  50.                 return ans
  51.    
  52.         ans.extend(tmp.palinidx)
  53.         return ans
  54.    
  55.     def isplin(self,w):

  56.         return w == w[::-1]
  57.                
  58.                
  59. class Solution(object):
  60.     def palindromePairs(self, words):
  61.         """
  62.         :type words: List[str]
  63.         :rtype: List[List[int]]
  64.         """
  65.         MyTrie = Trie()
  66.         for i in range(len(words)):
  67.             MyTrie.insert(words[i],i)
  68.         ans = []
  69.         for i in range(len(words)):
  70.             ans = ans + [ [idx,i]  for idx in MyTrie.find(words[i]) if idx != i]
  71.         return ans
  72.         
  73.         
复制代码
写了一个trie 检查了好几遍都觉得是O(n) 不明白为什么TLE
求帮忙

上一篇:出售10个月的leetcode
下一篇:感觉刷题到了一个瓶颈期怎么办。。。
推荐
magicsets 2018-2-17 07:10:11 | 只看该作者
全局:
greynut 发表于 2018-2-17 02:36
那请问有神么可以改进的地方吗?

但是我以为lc已经优化过,时间都是跟同种语言比的?

我试着优化了一下,感觉Python用普通Trie应该是没有办法Accept的,因为这道题目的输入的字符串都很长。

找了组LeetCode的测试数据,大概长这样:
  1. "hdhbaggbjiagiihgidda"
  2. "jj"
  3. "ihdebgbhejebgehebda"
  4. "fddhieigcggecjcjefga"
  5. "eeabdhhchghj"
  6. "hedeeggihjcddghhb"
  7. "hjdihahibjbi"
  8. ...
复制代码
输入字符串很长意味着Trie内的节点重复利用率低,也就是说输入总共有多少个字符,那么Trie里就会创建大致那个数量级的Node

而创建一个Node的overhead很大:Python需要为Node分配内存(一个dict),然后分配内存并初始化另一个dict结构children以及一个array结构palinidx —— 这个“常数因子”太大了。假设别人100ms可以跑完,而你的程序虽然是O(n),但均摊下来的单位操作要慢上100倍,那就是10s,也就超时了。

要想不超时的话,可能压缩Trie可以做到,或者就放弃Trie的做法吧。

评分

参与人数 1大米 +5 收起 理由
vegito2002 + 5 给你点个赞!

查看全部评分

回复

使用道具 举报

🔗
qdbwfn 2018-2-14 23:35:20 | 只看该作者
全局:
时间复杂度是O(n*len(word)^2)吧,再加上python本身比较慢
回复

使用道具 举报

🔗
 楼主| greynut 2018-2-17 02:36:05 | 只看该作者
全局:
qdbwfn 发表于 2018-2-14 23:35
时间复杂度是O(n*len(word)^2)吧,再加上python本身比较慢

那请问有神么可以改进的地方吗?

但是我以为lc已经优化过,时间都是跟同种语言比的?
回复

使用道具 举报

🔗
 楼主| greynut 2018-2-17 07:39:54 | 只看该作者
全局:
magicsets 发表于 2018-2-17 07:10
我试着优化了一下,感觉Python用普通Trie应该是没有办法Accept的,因为这道题目的输入的字符串都很长。
...

太感谢您了 回复写的很详细 感激感激
这是不是意味着用hashmap这题会比Trie要好

或者我不用dict存children,就用tuple,每次找一下,是不是可以消除常数因子的影响

太谢谢了 以前我都没有考虑到开dict的影响

回复

使用道具 举报

🔗
magicsets 2018-2-17 13:06:36 | 只看该作者
全局:
greynut 发表于 2018-2-17 07:39
太感谢您了 回复写的很详细 感激感激
这是不是意味着用hashmap这题会比Trie要好

是的用hashmap比较好

children用tuple或者list也会超时的,本质上是要创建的Node太多了
回复

使用道具 举报

🔗
 楼主| greynut 2018-2-17 13:10:55 | 只看该作者
全局:
magicsets 发表于 2018-2-17 13:06
是的用hashmap比较好

children用tuple或者list也会超时的,本质上是要创建的Node太多了

那为什么其他语言不会超时呢?

是因为python什么特性吗

那我万一面试要实现trie怎么办呢?
回复

使用道具 举报

🔗
magicsets 2018-2-17 13:22:32 | 只看该作者
全局:
greynut 发表于 2018-2-17 13:10
那为什么其他语言不会超时呢?

是因为python什么特性吗

其他语言也不一定不超时吧,也有可能正好卡在时间线上,比如python要5秒跑完,Java要1秒,而LeetCode卡2秒,那python的就TLE了。

面试要实现trie要么不会出这道题目,要么不会测试同样量级的数据,要么不会卡同样短的时间。

换言之,这道题你是正确地用python实现了trie,但题目本身的测试数据并不是为测试你用trie解决该问题的能力而设计的。
回复

使用道具 举报

🔗
sizem 2018-2-18 14:18:13 | 只看该作者
全局:
magicsets 发表于 2018-2-17 13:22
其他语言也不一定不超时吧,也有可能正好卡在时间线上,比如python要5秒跑完,Java要1秒,而LeetCode卡2 ...

之前有遇一題,我試試用人家的答案跑一下看看有多快,cod基本上跟我的一樣。。。我precompute一個sum(兩個int加起來而己啊!),在for loop裡取用,媽的,給我TLE。不precompute卻跑完所有test cases。
從此我對leetcode有一種既愛既恨的感覺。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表