# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None
classSolution: defdiameterOfBinaryTree(self, root: TreeNode) -> int: if root == None: # None Case return0 result = -1 defdepth(node: TreeNode): nonlocal result left = 0 right = 0 if node.left != None: left = depth(node.left) + 1 if node.right != None: right = depth(node.right) + 1 result = max(left + right, result) returnmax(left, right) depth(root) return result
classSolution: defcountCharacters(self, words: List[str], chars: str) -> int: ret_value = 0 for word in words: for c in word: if word.count(c) > chars.count(c): break else: ret_value += len(word) return ret_value
然后我们用哈希表优化,使其不用重复调用 count 。然而跑出来的结果并没有优化多少。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defcountCharacters(self, words: List[str], chars: str) -> int: ret_value = 0 chars_count = {} for c in chars: if c notin chars_count: chars_count[c] = chars.count(c) for word in words: for c in word: if c notin chars_count or word.count(c) > chars_count[c]: break else: ret_value += len(word) return ret_value
看了所有解答中,最快的两个答案,第一个答案如下所示,就是不用 count ,自己手写,第二个则是与我前面的最开始的解答完全一样,只不过用的是标志位,我用的是 for … else 。然鹅他时间是我的 1/2 …… 时间第一由算法复杂度决定,第二由运气决定可还行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution: # 最快的解答 defcountCharacters(self, words: List[str], chars: str) -> int: mine = {} res = 0 for c in chars: if c notin mine: mine[c] = 0 mine[c] += 1 for w in words: tmp = mine.copy() yes = 1 for t in w: if t notin tmp or tmp[t] <= 0: yes=0 break tmp[t] -= 1 if yes: res+=len(w) return res
classSolution: deflongestPalindrome(self, s: str) -> int: count_dict = {} ans = 0 for c in s: if c notin count_dict: count_dict[c] = 1 else: count_dict[c] += 1 for v in count_dict.values(): if v % 2 == 0: ans += v else: ans += v - 1 if ans < len(s): ans += 1 return ans
结果发现速度垫底……思来想去觉得已经很好了啊。于是去偷看了速度第一的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution: # 速度最快的实现,LeetCode 不显示作者信息 deflongestPalindrome(self, s: str) -> int: # i = 0 # j = len(s) -1 # max_sub_str = [] # while i < j: # if s[i] == s[j]: # max_sub_str.append() a = set(s) b = list(a) oddc = 0 flag = 0 for i inrange(len(b)): c = s.count(b[i]) if c % 2 != 0: oddc += 1 flag = 1 l = len(s) - (oddc - flag) return l
前面一堆注释可能是后来改了,看后面,我们发现他的思路是减回去而不是加上去,这样他在遍历 b 时(其实等效于我遍历哈希表),只需要对奇数出现的字符做操作,偶数是没有 else 的,这样可以少做一点操作。最后如果出现过奇数的元素,加一(即flag的作用),减去所有奇数字符个数即可。于是我用类似的思路优化了代码如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution: deflongestPalindrome(self, s: str) -> int: count_dict = {} odd_count = 0 flag = 0 for c in s: if c notin count_dict: count_dict[c] = 1 else: count_dict[c] += 1 for v in count_dict.values(): if v % 2 != 0: odd_count += 1 flag = 1 returnlen(s) - odd_count + flag
结果超越了 86% 的用户,可是时间几乎还是他的两倍…… 不过也不强求了,理论上来说,他对每一种出现了的字符调用 count,对于 s 的遍历要更多,而我只遍历了一次 s ,应该这方面更快啊…… 可能的原因是 count API 实现有骚操作?或者我使用 dict,哈希表有额外运算?再或者大概就是测试集差异,纯看运气了……