Python LeetCode(九)
不会做
1. Path Sum
class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
if root is None:
return False
if root.left is None and root.right is None and sum == root.val:
return True
return self.hasPathSum(root.left, sum-root.val) or self.hasPathSum(root.right, sum-root.val)
class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
if root:
diff = sum - root.val
if root.left or root.right:
left = self.hasPathSum(root.left, diff)
right = self.hasPathSum(root.right, diff)
return left or right
return diff == 0
return False
class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
if not root: return False
#children = [c for c in (root.left, root.right) if c]
for c in (root.left, root.right):
if c and self.hasPathSum(c, sum - root.val):
return True
return not (root.left or root.right) and sum == root.val
class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
def DFS(node, current_sum, sum_dict):
current_sum += node.val
# if this is a leaf node:
if not node.left and not node.right:
sum_dict[current_sum] = 1
if node.left:
DFS(node.left, current_sum, sum_dict)
if node.right:
DFS(node.right, current_sum, sum_dict)
current_sum -= node.val
if not root:
return False
sum_dict = dict()
DFS(root, 0, sum_dict)
if sum in sum_dict:
return True
return False
2. Find Duplicate Subtrees
import collections
class Solution(object):
def findDuplicateSubtrees(self, root):
"""
:type root: TreeNode
:rtype: List[TreeNode]
"""
def merkle(node):
if not node:
return '#'
left = merkle(node.left)
right = merkle(node.right)
index = left + right + str(node.val)
count[index].append(node)
return index
count = collections.defaultdict(list)
merkle(root)
return [nodes[0] for nodes in count.values() if nodes[1:]]
import collections
class Solution(object):
def findDuplicateSubtrees(self, root):
"""
:type root: TreeNode
:rtype: List[TreeNode]
"""
from hashlib import sha256
def hash_(x):
s = sha256()
s.update(x)
return s.hexdigest()
def merkle(node):
if not node:
return '#'
left = merkle(node.left)
right = merkle(node.right)
index = hash_(left + str(node.val) + right)
count[index].append(node)
return index
count = collections.defaultdict(list)
merkle(root)
return [nodes[0] for nodes in count.values() if nodes[1:]]
3. Copy List with Random Pointer
复制
class Solution(object):
def copyRandomList(self, head):
"""
:type head: RandomListNode
:rtype: RandomListNode
"""
def cloneNodes(head):
if head:
# new node sits next to old node
cur = head
while cur:
new_cur = RandomListNode(cur.label)
new_cur.next = cur.next
cur.next = new_cur
cur = new_cur.next
return head
def setRandoms(head):
if head:
# new node's random is old node's random's next
prev = head
cur = head.next
while cur:
cur.random = prev.random.next if prev.random else None
prev = cur.next
cur = prev.next if prev else None
return head
def extractClone(head):
if head:
# split two lists
oldhead = head
newhead = head.next
curold = head
curnew = newhead
while curold and curnew:
curold.next = curnew.next
curnew.next = curnew.next.next if curnew.next else None
curold = curold.next
curnew = curnew.next
return (oldhead,newhead)
return (None,None)
head = cloneNodes(head)
head = setRandoms(head)
head,newhead = extractClone(head)
return newhead
递归
class Solution(object):
mp = dict()
def copyRandomList(self, head):
"""
:type head: RandomListNode
:rtype: RandomListNode
"""
if head is None:
return None
if head in self.mp:
return self.mp[head]
self.mp[head] = RandomListNode(head.label)
self.mp[head].next = self.copyRandomList(head.next)
self.mp[head].random = self.copyRandomList(head.random)
return self.mp[head]
哈希
class Solution(object):
def copyRandomList(self, head):
"""
:type head: RandomListNode
:rtype: RandomListNode
"""
dic = dict()
m = n = head
while m:
dic[m] = RandomListNode(m.label)
m = m.next
dic[None] = None
while n:
dic[n].next = dic[n.next]
dic[n].random = dic[n.random]
n = n.next
return dic[head]
4. Valid Triangle Number
数学思想
class Solution(object):
def triangleNumber(self, nums):
ans = 0
nums.sort()
for i in range(2, len(nums)):
start = 0
end = i - 1
while start < end:
if nums[start] + nums[end] > nums[i]:
ans += end - start
end -= 1
else:
start += 1
return ans
确定两个+二分
class Solution(object):
def triangleNumber(self, nums):
ans = 0
nums.sort()
l = len(nums)
for i in range(l):
for j in range(i+1, l):
s = nums[i] + nums[j]; left, right = j + 1, l
while left < right:
mid = int((left + right) / 2)
if nums[mid] < s:
left = mid+1
else:
right = mid
ans += right - j - 1
return ans
???
class Solution(object):
def triangleNumber(self, nums):
counter = collections.Counter(nums) # AC
counter.pop(0, None)
uniq = sorted(counter.keys())
cnt = [0]
# 计算个数
for x in uniq:
cnt.append(cnt[-1] + counter[x])
ans = 0
for j, v in enumerate(uniq):
k = len(uniq) - 1
i = j
while 0 <= i <= j <= k:
while k > j and uniq[i] + uniq[j] <= uniq[k]:
k -= 1
if i < j:
ans += counter[uniq[i]] * counter[uniq[j]] * (cnt[k + 1] - cnt[j + 1])
ans += counter[uniq[i]] * counter[uniq[j]] * (counter[uniq[j]] - 1) / 2
else:
ans += counter[uniq[i]] * (counter[uniq[i]] - 1) / 2 * (cnt[k + 1] - cnt[j + 1])
ans += counter[uniq[i]] * (counter[uniq[i]] - 1) * (counter[uniq[i]] - 2) / 6
i -= 1
return ans
优化一下
1. 3Sum
数组两边移动
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
nums.sort()
for i in xrange(len(nums)-2):
if nums[i] > 0 or (i > 0 and nums[i] == nums[i-1]):
continue
l, r = i+1, len(nums)-1
while l < r:
s = nums[i] + nums[l] + nums[r]
if s < 0:
l +=1
elif s > 0:
r -= 1
else:
res.append((nums[i], nums[l], nums[r]))
while l < r and nums[l] == nums[l+1]:
l += 1
while l < r and nums[r] == nums[r-1]:
r -= 1
l += 1; r -= 1
return res
class Solution(object):
def towsum(self, nums, i, j, target):
res = []
while i < j:
s = nums[i] + nums[j]
if s < target:
i += 1
elif s > target:
j -= 1
else:
res.append([nums[i], nums[j]])
while i < j and nums[i] == nums[i+1]:
i += 1
while i < j and nums[j] == nums[j-1]:
j -= 1
i += 1
j -= 1
return res
def threeSum(self, nums):
nums.sort()
length = len(nums)
res = []
for i, n in enumerate(nums):
if n > 0: return res # 如果第一个数都大于0,后面不再考虑
if i == 0 or nums[i] != nums[i-1]:
r = self.towsum(nums, i+1, length-1, -n)
if r:
for x in r:
res.append([n] + x)
return res
统计正负数
import collections
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
counter = collections.defaultdict(int)
for x in nums:
counter[x] += 1
uniq = counter.keys() # 不重复的值
pos = sorted(x for x in uniq if x >= 0) # 正数
neg = sorted(x for x in uniq if x < 0) # 负数
if 0 in counter and counter[0] >= 3:
res.append([0]*3)
for p in pos:
for n in neg:
r = -(p+n)
if r in counter:
if (r == p or r == n) and counter[r] > 1:
res.append([n, r, p]) # r相等,放在中间
elif r < n:
res.append([r, n, p]) # r最小
elif r > p:
res.append([n, p, r]) # r最大
return res
2. Maximum Average Subarray I
class Solution(object):
def findMaxAverage(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: float
"""
length = len(nums)
temp = nums[:k]
max_val = sum(temp)
for i in xrange(k, length):
temp.pop(0)
temp.append(nums[i])
if sum(temp) > max_val:
max_val = sum(temp)
return max_val/float(k)
class Solution(object):
def findMaxAverage(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: float
"""
s = sum(nums[:k])
m = s
for i in range(k, len(nums)):
s += nums[i] - nums[i-k]
m = max(m, s)
return m / float(k)
class Solution(object):
def findMaxAverage(self, nums, k):
s = [0]
for x in nums:
s.append(s[-1]+x)
ma = max(s[i+k] - s[i] for i in range(len(nums)-k+1))
return ma / float(k)
关注公众号:数据结构与算法那些事儿,每天一篇数据结构与算法





浙公网安备 33010602011771号