Skip to content

Commit d63b770

Browse files
committed
no message
1 parent 138947d commit d63b770

9 files changed

+203
-1
lines changed

problems/python/substring-with-concatenation-of-all-words.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ def test(self, s, wl, countExpected):
4747

4848
return True
4949

50-
50+
51+
52+

problems/python3/3sum-smaller.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Solution:
2+
def threeSumSmaller(self, nums: List[int], target: int) -> int:
3+
N = len(nums)
4+
ans = 0
5+
6+
nums.sort()
7+
8+
9+
for i in range(N):
10+
j = i+1
11+
k = N-1
12+
while j<k:
13+
if nums[i]+nums[j]+nums[k]<target:
14+
ans += k-j
15+
j += 1
16+
else:
17+
k -= 1
18+
return ans

problems/python3/3sum.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,28 @@ def threeSum(self, nums: List[int]) -> List[List[int]]:
3737
k -= 1
3838
j += 1
3939

40+
return ans
41+
42+
43+
"""
44+
No Sort.
45+
Use set to dedupe and check needed.
46+
47+
Time: O(N^2)
48+
Space: O(N)
49+
"""
50+
class Solution:
51+
def threeSum(self, nums: List[int]) -> List[List[int]]:
52+
ans = set()
53+
seen = set()
54+
N = len(nums)
55+
56+
for i, v1 in enumerate(nums):
57+
if v1 in seen: continue
58+
seen.add(v1)
59+
needed = set()
60+
for j, v2 in enumerate(nums[i+1:]):
61+
if v2 in needed:
62+
ans.add(tuple(sorted((v1, v2, -v1-v2))))
63+
needed.add(-v1-v2)
4064
return ans

problems/python3/4sum.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
Time: O(N^(K-1)) -> O(N^3)
3+
Space: O(K) -> O(1)
4+
"""
5+
class Solution:
6+
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
7+
def kSum(k, start, target):
8+
if k>2:
9+
for i in range(start, len(nums)-k+1):
10+
if i!=start and nums[i]==nums[i-1]: continue
11+
temp.append(nums[i])
12+
kSum(k-1, i+1, target-nums[i])
13+
temp.pop()
14+
else:
15+
l, r = start, len(nums)-1
16+
17+
while l<r:
18+
if nums[l]+nums[r]>target:
19+
r -= 1
20+
elif nums[l]+nums[r]<target:
21+
l += 1
22+
else:
23+
ans.append(temp+[nums[l], nums[r]])
24+
while l<r and nums[l+1]==nums[l]: l += 1
25+
while l<r and nums[r-1]==nums[r]: r -= 1
26+
l += 1
27+
r -= 1
28+
29+
ans = []
30+
temp = []
31+
nums.sort()
32+
kSum(4, 0, target)
33+
return ans
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""
2+
Time: O(N)
3+
Space: O(LogN) Recursion stack. If the tree is balanced.
4+
"""
5+
class Solution:
6+
def isBalanced(self, root: Optional[TreeNode]) -> bool:
7+
def getHeight(node) -> (bool, int):
8+
if not node: return True, 0
9+
leftIsBalanced, leftHeight = getHeight(node.left)
10+
if not leftIsBalanced: return False, 0
11+
12+
rightIsBalanced, rightHeight = getHeight(node.right)
13+
if not rightIsBalanced: return False, 0
14+
15+
return abs(leftHeight-rightHeight)<2, 1+max(leftHeight, rightHeight)
16+
17+
isBalanced, h = getHeight(root)
18+
return isBalanced
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""
2+
Time: O(N)
3+
Space: O(LogN) for the recursion stack. If the tree is balanced.
4+
"""
5+
class Solution:
6+
def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
7+
def helper(node):
8+
if not node: return 0
9+
l = helper(node.left)
10+
r = helper(node.right)
11+
self.ans = max(self.ans, 1+l+r)
12+
return 1+max(l, r)
13+
14+
self.ans = 0
15+
16+
helper(root)
17+
return self.ans-1
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
Recursive
3+
Time: O(N)
4+
Space: O(LogN)
5+
"""
6+
class Solution:
7+
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
8+
if not root: return root
9+
left = root.left
10+
right = root.right
11+
root.left = self.invertTree(right)
12+
root.right = self.invertTree(left)
13+
return root
14+
15+
16+
"""
17+
Iterative
18+
Time: O(N)
19+
Space: O(N)
20+
"""
21+
class Solution:
22+
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
23+
if not root: return root
24+
q = collections.deque([root])
25+
26+
while q:
27+
node = q.popleft()
28+
left = node.left
29+
right = node.right
30+
node.right = left
31+
node.left = right
32+
33+
if node.left: q.append(node.left)
34+
if node.right: q.append(node.right)
35+
36+
return root
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""
2+
Time: O(N)
3+
Space:O(LogN), for recursion stack space.
4+
"""
5+
class Solution:
6+
def maxDepth(self, root: Optional[TreeNode]) -> int:
7+
if not root: return 0
8+
return 1+max(self.maxDepth(root.left), self.maxDepth(root.right))
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""
2+
Time: O(W * N/W * W), there will be W time of iteration in the first loop ([0]), N/W of iteration in the second loop ([1]). In each loop, creating substring "word" and "popWord" takes O(W).
3+
Space: O(MW) for "wordSet".
4+
"""
5+
class Solution:
6+
def findSubstring(self, s: str, words: List[str]) -> List[int]:
7+
N = len(s)
8+
M = len(words)
9+
W = len(words[0])
10+
wordSet = set(words)
11+
ans = []
12+
counter = collections.Counter(words)
13+
14+
for i in range(W): #[0]
15+
windowCounter = collections.Counter() #counter for the word in words
16+
notInWords = 0 #number of word not in the wordSet
17+
theSame = 0 #number of word with the same count with "counter"
18+
j = i
19+
20+
while j<N: #[1]
21+
word = s[j:j+W]
22+
if word in wordSet:
23+
windowCounter[word] += 1
24+
if windowCounter[word]==counter[word]:
25+
theSame += 1
26+
elif windowCounter[word]>counter[word]:
27+
theSame -= 1
28+
else:
29+
notInWords += 1
30+
31+
popStart = j-M*W
32+
if popStart>=0:
33+
popWord = s[popStart:popStart+W]
34+
if popWord in wordSet:
35+
windowCounter[popWord] -= 1
36+
if windowCounter[popWord]==counter[popWord]:
37+
theSame += 1
38+
elif windowCounter[popWord]<counter[popWord]:
39+
theSame -= 1
40+
else:
41+
notInWords -= 1
42+
43+
if theSame==len(wordSet) and notInWords==0: ans.append(popStart+W)
44+
j += W
45+
46+
return ans

0 commit comments

Comments
 (0)