Skip to content

Commit 5c09b25

Browse files
Added anagrams
1 parent 62fb2d3 commit 5c09b25

File tree

1 file changed

+312
-7
lines changed

1 file changed

+312
-7
lines changed

round_1.py

Lines changed: 312 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# target = 9
88
# return [0, 1]
99
# Assume each input have exactly one solution
10+
# But you cannot assume all numbers are unique
1011
def two_sum(nums, target):
1112
length = len(nums)
1213
first = 0
@@ -90,6 +91,30 @@ def two_sum_hash(nums, target):
9091
return answer
9192

9293

94+
# There are duplicates, use list as the value of dictionary
95+
def two_sum_hash_list_as_value(nums, target):
96+
stores = dict()
97+
for index, value in enumerate(nums):
98+
if value in stores:
99+
stores[value].append(index)
100+
else:
101+
stores[value] = [index]
102+
result = [-2, -1]
103+
for i in range(len(nums)):
104+
remainder = target - nums[i]
105+
if remainder in stores:
106+
store = stores[remainder]
107+
if remainder == nums[i]:
108+
if len(store) == 2:
109+
result = store
110+
break
111+
else:
112+
continue
113+
result = [i, store[0]]
114+
break
115+
return result
116+
117+
93118
print('\n#1. Two Sum:')
94119
# two_sum_nums = [2, 7, 11, 15, 18, 20, 27]
95120
# two_sum_nums = [2, 7, 11]
@@ -100,11 +125,11 @@ def two_sum_hash(nums, target):
100125
# two_sum_target = 6
101126
# two_sum_target = 0
102127
two_sum_target = 7
103-
print(two_sum(two_sum_nums, two_sum_target))
104-
print(two_sum_1(two_sum_nums, two_sum_target))
105-
print(two_sum_2(two_sum_nums, two_sum_target))
128+
# print(two_sum(two_sum_nums, two_sum_target))
129+
# print(two_sum_1(two_sum_nums, two_sum_target))
130+
# print(two_sum_2(two_sum_nums, two_sum_target))
106131
print(two_sum_hash(two_sum_nums, two_sum_target))
107-
print('NOT done')
132+
print(two_sum_hash_list_as_value(two_sum_nums, two_sum_target))
108133

109134

110135
# 4. Median of Two Sorted Arrays
@@ -1110,6 +1135,159 @@ def rotate_image(matrix):
11101135
rotate_image(rotate_image_matrix)
11111136

11121137

1138+
# 49. Group Anagrams
1139+
# given: ["eat", "tea", "tan", "ate", "nat", "bat"]
1140+
# All inputs will be in lower-case
1141+
# return:
1142+
# [
1143+
# ["ate", "eat","tea"],
1144+
# ["nat", "tan"],
1145+
# ["bat"]
1146+
# ]
1147+
# Time Limit Exceeded, not happy
1148+
def group_anagrams_result_sorted(strs):
1149+
if strs is None:
1150+
return [[]]
1151+
length = len(strs)
1152+
if length == 0:
1153+
return [[]]
1154+
if length == 1:
1155+
return [[strs[0]]]
1156+
copy = list()
1157+
for word in strs:
1158+
copy.append(word)
1159+
for i in range(length):
1160+
temp = ''.join(sorted(copy[i]))
1161+
copy[i] = temp
1162+
counts = [0] * length
1163+
for j in range(length):
1164+
if counts[j] != 0:
1165+
continue
1166+
target = copy[j]
1167+
for k in range(j + 1, length):
1168+
if counts[k] != 0:
1169+
continue
1170+
if copy[k] == target:
1171+
counts[k] = j + 1
1172+
counts[j] = j + 1
1173+
indexes = dict()
1174+
for index, item in enumerate(counts):
1175+
if item in indexes:
1176+
indexes[item].append(index)
1177+
else:
1178+
indexes[item] = [index]
1179+
lengths = dict()
1180+
for key, value in indexes.items():
1181+
lengths[key] = len(value)
1182+
length_indexes = dict()
1183+
for key, value in lengths.items():
1184+
if value in length_indexes:
1185+
length_indexes[value].append(key)
1186+
else:
1187+
length_indexes[value] = [key]
1188+
result = list()
1189+
the_length = len(length_indexes)
1190+
for l in range(the_length):
1191+
max_index = max(length_indexes)
1192+
max_item = length_indexes[max_index]
1193+
for each_item in max_item:
1194+
temp = [strs[m] for m in indexes[each_item]]
1195+
result.append(temp)
1196+
del length_indexes[max_index]
1197+
return result
1198+
1199+
1200+
# Time Limit Exceeded, not happy
1201+
def group_anagrams_result_not_sorted(strs):
1202+
if strs is None:
1203+
return [[]]
1204+
length = len(strs)
1205+
if length == 0:
1206+
return [[]]
1207+
if length == 1:
1208+
return [[strs[0]]]
1209+
copy = list()
1210+
for word in strs:
1211+
copy.append(word)
1212+
for i in range(length):
1213+
temp = ''.join(sorted(copy[i]))
1214+
copy[i] = temp
1215+
counts = [0] * length
1216+
for j in range(length):
1217+
if counts[j] != 0:
1218+
continue
1219+
target = copy[j]
1220+
for k in range(j + 1, length):
1221+
if counts[k] != 0:
1222+
continue
1223+
if copy[k] == target:
1224+
counts[k] = j + 1
1225+
counts[j] = j + 1
1226+
indexes = dict()
1227+
for index, item in enumerate(counts):
1228+
if item in indexes:
1229+
indexes[item].append(index)
1230+
else:
1231+
indexes[item] = [index]
1232+
result = list()
1233+
for key, value in indexes.items():
1234+
result.append([strs[l] for l in value])
1235+
return result
1236+
1237+
1238+
# https://www.youtube.com/watch?v=DhiT3hDt3ZA
1239+
# I think the one is not correct
1240+
# This one is answer to the following problem:
1241+
# https://www.lintcode.com/en/problem/anagrams/
1242+
def group_anagrams_jikai_tang(strs):
1243+
dic = {}
1244+
res = []
1245+
for word in strs:
1246+
ordered_str = str(sorted(word))
1247+
print(ordered_str)
1248+
if ordered_str in dic:
1249+
dic[ordered_str].append(word)
1250+
else:
1251+
dic[ordered_str] = [word]
1252+
for key in dic:
1253+
if len(dic[key]) >= 2:
1254+
res += dic[key]
1255+
return res
1256+
1257+
1258+
# http://www.cnblogs.com/zuoyuan/p/3769993.html
1259+
# Finally accepted. but only 42%, not good enough, will do it later
1260+
def group_anagrams_zuoyuan(strs):
1261+
if strs is None:
1262+
return [[]]
1263+
length = len(strs)
1264+
if length == 0:
1265+
return [[]]
1266+
if length == 1:
1267+
return [[strs[0]]]
1268+
dic = {}
1269+
res = []
1270+
for word in strs:
1271+
sorted_word = ''.join(sorted(word))
1272+
if sorted_word in dic:
1273+
dic[sorted_word].append(word)
1274+
else:
1275+
dic[sorted_word] = [word]
1276+
for key, value in dic.items():
1277+
res.append(value)
1278+
return res
1279+
1280+
1281+
group_anagrams_strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
1282+
# group_anagrams_strs = ["", "b", 'c', 'ab', 'ba', 'ab']
1283+
print('\n49. Group Anagrams:')
1284+
print(group_anagrams_result_sorted(group_anagrams_strs))
1285+
print(group_anagrams_result_not_sorted(group_anagrams_strs))
1286+
# print(group_anagrams_jikai_tang(group_anagrams_strs))
1287+
print(group_anagrams_zuoyuan(group_anagrams_strs))
1288+
print('NOT DONE')
1289+
1290+
11131291
# 53. Maximum Subarray
11141292
# Find the contiguous subarray within an array(len >= 1) which has the largest sum.
11151293
# Array = [−2,1,−3,4,−1,2,1,−5,4]
@@ -2771,7 +2949,7 @@ def product_except_self_constant_space(nums):
27712949
# s = "anagram", t = "nagaram", return true.
27722950
# s = "rat", t = "car", return false.
27732951
# only lowercase alphabets
2774-
def is_anagram(s, t):
2952+
def is_anagram_lowercase(s, t):
27752953
stores = dict()
27762954
for i in range(97, 123):
27772955
stores[chr(i)] = 0
@@ -2785,10 +2963,48 @@ def is_anagram(s, t):
27852963
return True
27862964

27872965

2966+
# This one is faster than the lowercase one
2967+
def is_anagram_dict(s, t):
2968+
s_len = len(s)
2969+
t_len = len(t)
2970+
if s_len != t_len:
2971+
return False
2972+
letters = dict()
2973+
for item in s:
2974+
if item in letters:
2975+
letters[item] += 1
2976+
else:
2977+
letters[item] = 1
2978+
for letter in t:
2979+
if letter not in letters:
2980+
return False
2981+
letters[letter] -= 1
2982+
if letters[letter] < 0:
2983+
return False
2984+
return True
2985+
2986+
2987+
# Faster than lowercase but slower than dict one
2988+
def is_anagram_sort_first(s, t):
2989+
s_len = len(s)
2990+
t_len = len(t)
2991+
if s_len != t_len:
2992+
return False
2993+
s = ''.join(sorted(s))
2994+
t = ''.join(sorted(t))
2995+
if s == t:
2996+
return True
2997+
else:
2998+
return False
2999+
3000+
27883001
print('\n#242. Valid Anagram:')
27893002
is_anagram_s = 'anagram'
27903003
is_anagram_t = 'nagaram'
2791-
print(is_anagram(is_anagram_s, is_anagram_t))
3004+
print(is_anagram_lowercase(is_anagram_s, is_anagram_t))
3005+
print(is_anagram_dict(is_anagram_s, is_anagram_t))
3006+
print(is_anagram_sort_first(is_anagram_s, is_anagram_t))
3007+
print(is_anagram_sort_first('', ''))
27923008

27933009

27943010
# 258. Add Digits:
@@ -3674,6 +3890,32 @@ def guess_number(n):
36743890
print('NOT done')
36753891

36763892

3893+
# 378. Kth Smallest Element in a Sorted Matrix
3894+
# n x n matrix, rows and columns are sorted in ascending order
3895+
# Find the kth smallest element in the matrix
3896+
# It is the kth smallest element in the sorted order, not the kth distinct element
3897+
# 1 <= k <= n^2
3898+
def kth_smallest(matrix, k):
3899+
length = len(matrix)
3900+
positions = [0] * length
3901+
result = matrix[0][0]
3902+
if k == 1:
3903+
return result
3904+
count = 1
3905+
print('NOT DONE')
3906+
return positions * count
3907+
3908+
3909+
kth_smallest_matrix = [
3910+
[1, 5, 9],
3911+
[10, 11, 13],
3912+
[12, 13, 15]
3913+
]
3914+
kth_smallest_k = 8
3915+
print('\n#378. Kth Smallest Element in a Sorted Matrix:')
3916+
print(kth_smallest(kth_smallest_matrix, kth_smallest_k))
3917+
3918+
36773919
# 383. Ransom Note
36783920
# Use magazine to construct ransom_note
36793921
# Each letter in the magazine can only be used once in your ransom note
@@ -4029,7 +4271,7 @@ def find_anagrams(s, p):
40294271
return []
40304272
result = list()
40314273
for i in range(s_len - p_len + 1):
4032-
if is_anagram(s[i:i + p_len], p):
4274+
if is_anagram_lowercase(s[i:i + p_len], p):
40334275
result.append(i)
40344276
return result
40354277

@@ -4052,10 +4294,73 @@ def is_anagram(a, b):
40524294
return True
40534295

40544296

4297+
# Submission Result: Time Limit Exceeded
4298+
def find_anagrams_sort_first(s, p):
4299+
if s is None or p is None:
4300+
return []
4301+
s_len = len(s)
4302+
p_len = len(p)
4303+
if s_len < p_len:
4304+
return []
4305+
target = ''.join(sorted(p))
4306+
result = []
4307+
for i in range(s_len - p_len + 1):
4308+
word = s[i:i + p_len]
4309+
sorted_word = ''.join(sorted(word))
4310+
if sorted_word == target:
4311+
result.append(i)
4312+
return result
4313+
4314+
4315+
# Accepted, 96.31% and bug free, awesome!!!
4316+
def find_anagrams_dict(s, p):
4317+
if s is None or p is None:
4318+
return []
4319+
s_len = len(s)
4320+
p_len = len(p)
4321+
if s_len < p_len:
4322+
return []
4323+
if s_len == p_len:
4324+
if ''.join(sorted(s)) == ''.join(sorted(p)):
4325+
return [0]
4326+
else:
4327+
return []
4328+
target = {}
4329+
for letter in p:
4330+
if letter in target:
4331+
target[letter] += 1
4332+
else:
4333+
target[letter] = 1
4334+
result = []
4335+
current = {}
4336+
for i in range(p_len):
4337+
if s[i] in current:
4338+
current[s[i]] += 1
4339+
else:
4340+
current[s[i]] = 1
4341+
if current == target:
4342+
result.append(0)
4343+
for j in range(1, s_len - p_len + 1):
4344+
new_char = s[p_len + j - 1]
4345+
if new_char in current:
4346+
current[new_char] += 1
4347+
else:
4348+
current[new_char] = 1
4349+
remove_char = s[j - 1]
4350+
current[remove_char] -= 1
4351+
if current[remove_char] == 0:
4352+
del current[remove_char]
4353+
if current == target:
4354+
result.append(j)
4355+
return result
4356+
4357+
40554358
find_anagrams_s = 'abab'
40564359
find_anagrams_p = 'ab'
40574360
print('\n#438. Find All Anagrams in a String:')
40584361
print(find_anagrams(find_anagrams_s, find_anagrams_p))
4362+
print(find_anagrams_sort_first(find_anagrams_s, find_anagrams_p))
4363+
print(find_anagrams_dict(find_anagrams_s, find_anagrams_p))
40594364

40604365

40614366
# 448. Find all numbers disappeared in an array

0 commit comments

Comments
 (0)