├── .gitignore ├── README.md ├── .idea ├── .gitignore ├── vcs.xml ├── inspectionProfiles │ └── profiles_settings.xml ├── misc.xml ├── modules.xml └── leetcode.iml ├── episode65-2021-08-12 ├── q1486.py ├── q1791.py └── q1637.py ├── episode69-2021-08-26 ├── q1614.py └── q535.py ├── episode51-2021-06-24 ├── q1313.py ├── q1342.py └── q1769.py ├── episode53-2021-07-01 ├── q1720.py ├── q1165.py └── q1302.py ├── episode35-2021-04-29 ├── q1108_defanging_ip.py ├── q1480_cumsum.py └── q1570_dot_product_of_two_sparse_vectors.py ├── episode49-2021-06-17 ├── q1528-shuffle-string.py ├── q1281-subtract-the-product-and-sum-of-digits-of-an-integer.py └── q1769-minimum-number-of-operations-to-move-all-balls-to-each-box.py ├── episode67-2021-08-19 ├── q1859.py └── q938.py ├── episode39-2021-05-13 ├── q1470-shuffle-array.py ├── q1672_richest_customer_wealth.py └── q1431_kids_with_the_greatest_number_of_candies.py ├── episode45-2021-06-03 ├── q1874-minimize-product-sum-of-two-arrays.py └── q1476-subrectangle-queries.py ├── episode48-2021-06-13 ├── q1365-how-many-numbers-are-smaller-than-the-current-number.py ├── q1603-design-parking-system.py ├── q771-jewels-and-stones.py └── q1828-queries-on-number-of-points-inside-a-circle.py ├── episode55-2021-07-08 ├── q1920.py └── q1389.py ├── episode63-2021-08-05 ├── q1221.py └── q1282.py ├── episode57-2021-07-15 ├── q1678.py └── q1379.py ├── episode47-2021-06-10 ├── q1880-check-if-two-words-equal-summation-of-two-words.py └── q1512-number-of-good-pairs.py ├── episode59-2021-07-22 ├── q1773.py └── q807.py ├── episode43-2021-05-27 ├── merge_sort.py └── heap_sort.py ├── episode70-2021-09-02 ├── q760.py └── q1038.py ├── episode71-2021-09-09 └── q1.py ├── episode41-2021-05-18 └── sorting.py ├── episode72-2021-09-16 └── q121.py ├── episode33-2021-04-22 └── q1265_print_linked_list_in_reverse.py └── episode61-2021-07-29 └── q1315.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /venv 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # algorithms-leetcode-python-scha-poreshaem 2 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /episode65-2021-08-12/q1486.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def xorOperation(self, n: int, start: int) -> int: 3 | xor = start 4 | for i in range(1, n): 5 | xor = xor ^ (start + i * 2) 6 | return xor 7 | 8 | 9 | if __name__ == '__main__': 10 | n = 1 11 | start = 7 12 | print(Solution().xorOperation(n, start)) 13 | -------------------------------------------------------------------------------- /episode69-2021-08-26/q1614.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxDepth(self, s: str) -> int: 3 | depth = [0] 4 | for i, char in enumerate(s): 5 | depth.append(s[:i].count('(') - s[:i].count(')')) 6 | return max(depth) 7 | 8 | 9 | if __name__ == '__main__': 10 | s = "(1+(2*3)+((8)/4))+1" 11 | print(Solution().maxDepth(s)) 12 | -------------------------------------------------------------------------------- /episode51-2021-06-24/q1313.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def decompressRLElist(self, nums: list[int]) -> list[int]: 3 | n = len(nums) 4 | answer = [] 5 | for i in range(0, n, 2): 6 | answer += nums[i] * [nums[i+1]] 7 | return answer 8 | 9 | 10 | 11 | if __name__ == '__main__': 12 | nums = [1, 1, 2, 3] 13 | print(Solution().decompressRLElist(nums)) 14 | -------------------------------------------------------------------------------- /episode53-2021-07-01/q1720.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def decode(self, encoded: list[int], first: int) -> list[int]: 3 | decoded = [first] 4 | for i in range(len(encoded)): 5 | decoded.append(encoded[i] ^ decoded[i]) 6 | return decoded 7 | 8 | 9 | if __name__ == '__main__': 10 | encoded = [6, 2, 7, 3] 11 | first = 4 12 | print(Solution().decode(encoded, first)) 13 | -------------------------------------------------------------------------------- /episode65-2021-08-12/q1791.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findCenter(self, edges: List[List[int]]) -> int: 6 | if edges[0][0] in edges[1]: 7 | return edges[0][0] 8 | else: 9 | return edges[0][1] 10 | 11 | 12 | if __name__ == '__main__': 13 | edges = [[1, 2], [5, 1], [1, 3], [1, 4]] 14 | print(Solution().findCenter(edges)) 15 | -------------------------------------------------------------------------------- /episode35-2021-04-29/q1108_defanging_ip.py: -------------------------------------------------------------------------------- 1 | 2 | class Solution: 3 | def defangIPaddr(self, address: str) -> str: 4 | new_ip = '' 5 | for s in address: 6 | if s == '.': 7 | new_ip = new_ip + '[.]' 8 | else: 9 | new_ip = new_ip + s 10 | return new_ip 11 | 12 | if __name__ == '__main__': 13 | 14 | ip = "255.100.50.0" 15 | print(Solution().defangIPaddr(ip)) -------------------------------------------------------------------------------- /episode49-2021-06-17/q1528-shuffle-string.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def restoreString(self, s: str, indices: list[int]) -> str: 3 | 4 | new_s = [''] * len(s) 5 | 6 | for i, ind in enumerate(indices): 7 | new_s[ind] = s[i] 8 | 9 | return ''.join(new_s) 10 | 11 | 12 | if __name__ == '__main__': 13 | s = "codeleet" 14 | indices = [4, 5, 6, 7, 0, 2, 1, 3] 15 | print(Solution().restoreString(s, indices)) 16 | -------------------------------------------------------------------------------- /episode67-2021-08-19/q1859.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def sortSentence(self, s: str) -> str: 3 | shuffled = s.split(' ') 4 | n = len(shuffled) 5 | original = [''] * n 6 | 7 | for iword in shuffled: 8 | original[int(iword[-1]) - 1] += iword[:-1] 9 | 10 | return ' '.join(original) 11 | 12 | 13 | if __name__ == '__main__': 14 | s = "is2 sentence4 This1 a3" 15 | print(Solution().sortSentence(s)) 16 | -------------------------------------------------------------------------------- /episode39-2021-05-13/q1470-shuffle-array.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def shuffle(self, nums: List[int], n: int) -> List[int]: 6 | new_arr = [] 7 | for i in range(n): 8 | new_arr.append(nums[i]) 9 | new_arr.append(nums[i + n]) 10 | return new_arr 11 | 12 | 13 | if __name__ == '__main__': 14 | nums = [2, 5, 1, 3, 4, 7] 15 | n = 3 16 | print(Solution().shuffle(nums, n)) 17 | -------------------------------------------------------------------------------- /.idea/leetcode.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /episode45-2021-06-03/q1874-minimize-product-sum-of-two-arrays.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minProductSum(self, nums1: list[int], nums2: list[int]) -> int: 3 | nums1.sort() 4 | nums2.sort(reverse=True) 5 | n = len(nums1) 6 | s = 0 7 | for i in range(n): 8 | s = s + nums1[i] * nums2[i] 9 | return s 10 | 11 | 12 | if __name__ == '__main__': 13 | n1 = [1, 2] 14 | n2 = [4, 6] 15 | print(Solution().minProductSum(n1, n2)) 16 | -------------------------------------------------------------------------------- /episode48-2021-06-13/q1365-how-many-numbers-are-smaller-than-the-current-number.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def smallerNumbersThanCurrent(self, nums: list[int]) -> list[int]: 3 | nums_sorted = sorted(nums) # n log n 4 | answer = [] 5 | for i, el in enumerate(nums): # n 6 | nums[i] = nums_sorted.index(el) 7 | return nums 8 | 9 | 10 | if __name__ == '__main__': 11 | nums = [8, 1, 2, 2, 3] 12 | print(Solution().smallerNumbersThanCurrent(nums)) 13 | -------------------------------------------------------------------------------- /episode48-2021-06-13/q1603-design-parking-system.py: -------------------------------------------------------------------------------- 1 | class ParkingSystem: 2 | 3 | def __init__(self, big: int, medium: int, small: int): 4 | self.car_places = {1: big, 2: medium, 3: small} 5 | 6 | def addCar(self, carType: int) -> bool: 7 | self.car_places[carType] -= 1 8 | return self.car_places[carType] >= 0 9 | 10 | 11 | if __name__ == '__main__': 12 | ps = ParkingSystem(1, 1, 0) 13 | for car_type in [1, 2, 3, 1]: 14 | print(ps.addCar(car_type)) 15 | -------------------------------------------------------------------------------- /episode55-2021-07-08/q1920.py: -------------------------------------------------------------------------------- 1 | from operator import itemgetter 2 | 3 | class Solution: 4 | def buildArray(self, nums: list[int]) -> list[int]: 5 | ans = [] 6 | for el in nums: 7 | ans.append(nums[el]) 8 | return ans 9 | 10 | class Solution: 11 | def buildArray(self, nums: list[int]) -> list[int]: 12 | return list(map(nums.__getitem__, nums)) 13 | 14 | 15 | if __name__ == '__main__': 16 | nums = [0, 2, 1, 5, 3, 4] 17 | print(Solution().buildArray(nums)) 18 | -------------------------------------------------------------------------------- /episode63-2021-08-05/q1221.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def balancedStringSplit(self, s: str) -> int: 3 | balance = 0 4 | split_count = 0 5 | for char in s: 6 | if char == 'L': 7 | balance += 1 8 | else: 9 | balance -= 1 10 | 11 | if balance == 0: 12 | split_count += 1 13 | return split_count 14 | 15 | 16 | if __name__ == '__main__': 17 | s = "RLRRLLRLRL" 18 | print(Solution().balancedStringSplit(s)) 19 | -------------------------------------------------------------------------------- /episode51-2021-06-24/q1342.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def numberOfSteps(self, num: int) -> int: 3 | steps = 0 4 | while num: 5 | if num % 2: 6 | num = num - 1 7 | else: 8 | num = num / 2 9 | steps = steps + 1 10 | return steps 11 | 12 | class Solution: 13 | def numberOfSteps(self, num: int) -> int: 14 | return num // 2 - 1 if (num // 2) % 2 else num // 2 15 | 16 | 17 | if __name__ == '__main__': 18 | num = 8 19 | print(Solution().numberOfSteps(num)) -------------------------------------------------------------------------------- /episode53-2021-07-01/q1165.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def calculateTime(self, keyboard: str, word: str) -> int: 3 | cur = 0 4 | time = 0 5 | layout = {} 6 | for i, c in enumerate(keyboard): 7 | layout[c] = i 8 | 9 | for c in word: 10 | new = layout[c] 11 | time = time + abs(cur - new) 12 | cur = new 13 | 14 | return time 15 | 16 | 17 | if __name__ == '__main__': 18 | keyboard = "pqrstuvwxyzabcdefghijklmno" 19 | word = "leetcode" 20 | print(Solution().calculateTime(keyboard, word)) 21 | -------------------------------------------------------------------------------- /episode65-2021-08-12/q1637.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int: 6 | # O(nlog(n)) 7 | points.sort(key=lambda x: x[0]) 8 | gaps = [] 9 | n = len(points) 10 | # O(n) 11 | for i in range(1, n): 12 | gaps.append(points[i][0] - points[i - 1][0]) 13 | # O(n) 14 | return max(gaps) 15 | 16 | 17 | if __name__ == '__main__': 18 | points = [[8, 7], [9, 9], [7, 4], [9, 7]] 19 | print(Solution().maxWidthOfVerticalArea(points)) 20 | -------------------------------------------------------------------------------- /episode35-2021-04-29/q1480_cumsum.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def runningSum(self, nums: List[int]) -> List[int]: 6 | cumsum = [] 7 | s = 0 8 | for el in nums: 9 | s = s + el 10 | cumsum.append(s) 11 | return cumsum 12 | 13 | 14 | def runningSum(nums: List[int]) -> List[int]: 15 | for i in range(1, len(nums)): 16 | nums[i] = nums[i] + nums[i - 1] 17 | return nums 18 | 19 | 20 | if __name__ == '__main__': 21 | nums = [1, 2, 3] 22 | print(runningSum(nums)) 23 | print(nums) 24 | -------------------------------------------------------------------------------- /episode57-2021-07-15/q1678.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def interpret(self, command: str) -> str: 3 | command = list(command) 4 | n = len(command) 5 | for i in range(1, n): 6 | if command[i - 1] == '(' and command[i] == ')': 7 | command[i - 1] = '' 8 | command[i] = 'o' 9 | 10 | for i in range(n): 11 | if command[i] == '(' or command[i] == ')': 12 | command[i] = '' 13 | 14 | return ''.join(command) 15 | 16 | 17 | if __name__ == '__main__': 18 | command = "G()()()()(al)" 19 | print(Solution().interpret(command)) 20 | -------------------------------------------------------------------------------- /episode51-2021-06-24/q1769.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minOperations(self, boxes: str) -> list[int]: 3 | n = len(boxes) 4 | answers = [0] * n 5 | 6 | steps, curr = 0, 0 7 | for i in range(n): 8 | answers[i] += steps 9 | curr += int(boxes[i]) 10 | steps += curr 11 | 12 | steps, curr = 0, 0 13 | for i in range(n-1, -1, -1): 14 | answers[i] += steps 15 | curr += int(boxes[i]) 16 | steps += curr 17 | return answers 18 | 19 | 20 | if __name__ == '__main__': 21 | boxes = '110' 22 | print(Solution().minOperations(boxes)) 23 | -------------------------------------------------------------------------------- /episode55-2021-07-08/q1389.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def createTargetArray(self, nums: list[int], index: list[int]) -> list[int]: 3 | target = [] 4 | n = len(nums) 5 | # O(n**2) 6 | for i in range(n): 7 | target.insert(index[i], nums[i]) 8 | return target 9 | 10 | class Solution: 11 | def createTargetArray(self, nums: list[int], index: list[int]) -> list[int]: 12 | arr = [[index[i], nums[i]] for i in range(len(nums))] 13 | return arr, sorted(arr) 14 | 15 | 16 | 17 | if __name__ == '__main__': 18 | nums = [0, 1, 2, 3, 4] 19 | index = [0, 1, 2, 2, 1] 20 | print(Solution().createTargetArray(nums, index)) 21 | -------------------------------------------------------------------------------- /episode48-2021-06-13/q771-jewels-and-stones.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def numJewelsInStones(self, jewels: str, stones: str) -> int: 3 | stone_dict = {} 4 | for stone in stones: 5 | if stone in stone_dict: 6 | stone_dict[stone] += 1 7 | else: 8 | stone_dict[stone] = 1 9 | 10 | jewel_number = 0 11 | jewels = set(jewels) 12 | 13 | for stone, count in stone_dict.items(): 14 | if stone in jewels: # O(1) 15 | jewel_number = jewel_number + count 16 | 17 | return jewel_number 18 | 19 | 20 | if __name__ == '__main__': 21 | jewels = "aA" 22 | stones = "aAAbbbb" 23 | print(Solution().numJewelsInStones(jewels, stones)) 24 | -------------------------------------------------------------------------------- /episode47-2021-06-10/q1880-check-if-two-words-equal-summation-of-two-words.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def get_num_repr(self, word): 3 | codes = {'a': '0', 'b': '1', 'c': '2', 'd': '3', 'e': '4', 'f': '5', 'g': '6', 'h': '7', 'i': '8', 'j': '9'} 4 | s = '' 5 | for l in word: 6 | s = s + codes[l] 7 | return int(s) 8 | 9 | def isSumEqual(self, firstWord: str, secondWord: str, targetWord: str) -> bool: 10 | return self.get_num_repr(firstWord) + self.get_num_repr(secondWord) == self.get_num_repr(targetWord) 11 | 12 | 13 | if __name__ == '__main__': 14 | test_cases = [['acb', 'cba', 'cdb', True]] 15 | for test_case in test_cases: 16 | assert Solution().isSumEqual(*test_case[:3]) == test_case[3] 17 | 18 | -------------------------------------------------------------------------------- /episode45-2021-06-03/q1476-subrectangle-queries.py: -------------------------------------------------------------------------------- 1 | class SubrectangleQueries: 2 | 3 | def __init__(self, rectangle: list[list[int]]): 4 | self.rec = rectangle 5 | 6 | def updateSubrectangle(self, row1: int, col1: int, row2: int, col2: int, newValue: int) -> None: 7 | for i in range(row1, row2 + 1): 8 | for j in range(col1, col2 + 1): 9 | self.rec[i][j] = newValue 10 | 11 | def getValue(self, row: int, col: int) -> int: 12 | return self.rec[row][col] 13 | 14 | 15 | if __name__ == '__main__': 16 | rec = [[1, 2, 1], [4, 3, 4], [3, 2, 1], [1, 1, 1]] 17 | sq = SubrectangleQueries(rec) 18 | print(sq.rec) 19 | print(sq.getValue(0, 1)) 20 | sq.updateSubrectangle(0, 0, 3, 2, 5) 21 | print(sq.rec) 22 | -------------------------------------------------------------------------------- /episode69-2021-08-26/q535.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | 4 | class Codec: 5 | 6 | def __init__(self): 7 | self.url_db = {} 8 | 9 | def encode(self, longUrl: str) -> str: 10 | """Encodes a URL to a shortened URL. 11 | """ 12 | 13 | shortUrl = hashlib.sha1(longUrl.encode('utf-8')).hexdigest()[:6] 14 | self.url_db[shortUrl] = longUrl 15 | 16 | return shortUrl 17 | 18 | def decode(self, shortUrl: str) -> str: 19 | """Decodes a shortened URL to its original URL. 20 | """ 21 | return self.url_db[shortUrl] 22 | 23 | if __name__ == '__main__': 24 | c = Codec() 25 | url = 'abds' 26 | shorten = c.encode(url) 27 | print(shorten) 28 | original = c.decode(shorten) 29 | print(original) 30 | -------------------------------------------------------------------------------- /episode59-2021-07-22/q1773.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def countMatches(self, items: List[List[str]], ruleKey: str, ruleValue: str) -> int: 6 | 7 | if ruleKey == 'type': 8 | index = 0 9 | elif ruleKey == 'color': 10 | index = 1 11 | else: 12 | index = 2 13 | 14 | counter = 0 15 | for item in items: 16 | if item[index] == ruleValue: 17 | counter += 1 18 | return counter 19 | 20 | 21 | if __name__ == '__main__': 22 | items = [["phone", "blue", "pixel"], ["computer", "silver", "phone"], ["phone", "gold", "iphone"]] 23 | ruleKey = "type" 24 | ruleValue = "phone" 25 | print(Solution().countMatches(items, ruleKey, ruleValue)) 26 | -------------------------------------------------------------------------------- /episode48-2021-06-13/q1828-queries-on-number-of-points-inside-a-circle.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countPoints(self, points: list[list[int]], queries: list[list[int]]) -> list[int]: 3 | 4 | points_inside = [] 5 | 6 | for querie in queries: 7 | num_points_inside = 0 8 | for point in points: 9 | if (querie[0] - point[0]) ** 2 + (querie[1] - point[1]) ** 2 <= querie[2] ** 2: 10 | num_points_inside = num_points_inside + 1 11 | points_inside.append(num_points_inside) 12 | 13 | return points_inside 14 | 15 | 16 | if __name__ == '__main__': 17 | points = [[1, 3], [3, 3], [5, 3], [2, 2]] 18 | queries = [[2, 3, 1], [4, 3, 1], [1, 1, 2]] 19 | print(Solution().countPoints(points, queries)) 20 | -------------------------------------------------------------------------------- /episode59-2021-07-22/q807.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxIncreaseKeepingSkyline(self, grid: List[List[int]]) -> int: 6 | increase = 0 7 | n = len(grid) 8 | 9 | max_for_rows = [] 10 | for i in range(n): 11 | max_for_rows.append(max(grid[i])) 12 | 13 | max_for_cols = [] 14 | for i in range(n): 15 | max_for_cols.append(max([row[i] for row in grid])) 16 | 17 | for i in range(n): 18 | for j in range(n): 19 | increase += min(max_for_rows[i], max_for_cols[j]) - grid[i][j] 20 | 21 | return increase 22 | 23 | 24 | if __name__ == '__main__': 25 | grid = [[3, 0, 8, 4], [2, 4, 5, 7], [9, 2, 6, 3], [0, 3, 1, 0]] 26 | print(Solution().maxIncreaseKeepingSkyline(grid)) 27 | -------------------------------------------------------------------------------- /episode43-2021-05-27/merge_sort.py: -------------------------------------------------------------------------------- 1 | def merge(arr1, arr2): 2 | merged = [] 3 | i, j = 0, 0 4 | 5 | while i < len(arr1) and j < len(arr2): 6 | if arr1[i] < arr2[j]: 7 | merged.append(arr1[i]) 8 | i = i + 1 9 | else: 10 | merged.append(arr2[j]) 11 | j = j + 1 12 | 13 | while i < len(arr1): 14 | merged.append(arr1[i]) 15 | i = i + 1 16 | 17 | while j < len(arr2): 18 | merged.append(arr2[j]) 19 | j = j + 1 20 | 21 | return merged 22 | 23 | 24 | def merge_sort(arr): 25 | if len(arr) < 2: 26 | return arr 27 | 28 | m = len(arr) // 2 29 | 30 | return merge(merge_sort(arr[:m]), merge_sort(arr[m:])) 31 | 32 | 33 | if __name__ == '__main__': 34 | arr1 = [3, 4, 90] 35 | arr2 = [1, 2, 3, 100] 36 | arr = [5,2,3,1] 37 | print(merge_sort(arr)) 38 | -------------------------------------------------------------------------------- /episode70-2021-09-02/q760.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def anagramMappings(self, nums1: List[int], nums2: List[int]) -> List[int]: 6 | mapping = [] 7 | # O(n**2) 8 | for el in nums1: 9 | mapping.append(nums2.index(el)) 10 | return mapping 11 | 12 | 13 | class Solution: 14 | def anagramMappings(self, nums1: List[int], nums2: List[int]) -> List[int]: 15 | mapping_d = {} 16 | # O(n) 17 | for i, el in enumerate(nums2): 18 | mapping_d[el] = i 19 | 20 | mapping = [] 21 | # O(n) 22 | for el in nums1: 23 | mapping.append(mapping_d[el]) 24 | 25 | return mapping 26 | 27 | 28 | if __name__ == '__main__': 29 | nums1 = [12, 28, 46, 32, 50] 30 | nums2 = [50, 12, 32, 46, 28] 31 | print(Solution().anagramMappings(nums1, nums2)) 32 | -------------------------------------------------------------------------------- /episode49-2021-06-17/q1281-subtract-the-product-and-sum-of-digits-of-an-integer.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def subtractProductAndSum(self, n: int) -> int: 3 | n_str = str(n) 4 | 5 | product = 1 6 | summ = 0 7 | for num in n_str: 8 | product = product * int(num) 9 | summ = summ + int(num) 10 | 11 | return product - summ 12 | 13 | 14 | class Solution: 15 | def subtractProductAndSum(self, n: int) -> int: 16 | 17 | product = 1 18 | summ = 0 19 | mult = 0 20 | while n // 10**mult: 21 | digit = (n % 10**(mult+1)) // 10**mult 22 | product = product * digit 23 | summ = summ + digit 24 | mult = mult + 1 25 | 26 | return product - summ 27 | 28 | 29 | 30 | if __name__ == '__main__': 31 | n = 234 32 | print(Solution().subtractProductAndSum(n)) -------------------------------------------------------------------------------- /episode43-2021-05-27/heap_sort.py: -------------------------------------------------------------------------------- 1 | def print_tree(arr, i=0, level=0): 2 | if i < len(arr): 3 | print_tree(arr, i=2 * i + 2, level=level + 1) 4 | print(3 * ' ' * level + str(arr[i])) 5 | print_tree(arr, i=2 * i + 1, level=level + 1) 6 | 7 | 8 | def heapify(arr, i, n): 9 | l = 2 * i + 1 10 | r = 2 * i + 2 11 | 12 | largest = i 13 | 14 | if l < n and arr[l] > arr[largest]: 15 | largest = l 16 | if r < n and arr[r] > arr[largest]: 17 | largest = r 18 | 19 | if largest != i: 20 | arr[i], arr[largest] = arr[largest], arr[i] 21 | heapify(arr, largest, n) 22 | 23 | 24 | def heap_sort(arr): 25 | n = len(arr) 26 | # build heap 27 | for i in range(n // 2 - 1, -1, -1): 28 | heapify(arr, i, n) 29 | 30 | for i in range(n - 1, -1, -1): 31 | arr[0], arr[i] = arr[i], arr[0] 32 | heapify(arr, 0, i) 33 | 34 | 35 | if __name__ == '__main__': 36 | nums = [1, 8, 3, 0, 5] 37 | print_tree(nums) 38 | heap_sort(nums) 39 | print(nums) 40 | -------------------------------------------------------------------------------- /episode47-2021-06-10/q1512-number-of-good-pairs.py: -------------------------------------------------------------------------------- 1 | from math import factorial 2 | 3 | 4 | class Solution: 5 | def numIdenticalPairs(self, nums: list[int]) -> int: 6 | n = len(nums) 7 | pairs = [] 8 | for i in range(n): 9 | for j in range(n): 10 | if nums[i] == nums[j] and i < j: 11 | pairs.append((i, j)) 12 | return pairs 13 | 14 | 15 | class Solution: 16 | def numIdenticalPairs(self, nums: list[int]) -> int: 17 | 18 | counter = {} 19 | for el in nums: 20 | if el in counter: 21 | counter[el] += 1 22 | else: 23 | counter[el] = 1 24 | 25 | pairs = 0 26 | 27 | for _, val in counter.items(): 28 | if val > 1: 29 | pairs += factorial(val) / (factorial(2) * factorial(val - 2)) 30 | 31 | return pairs 32 | 33 | 34 | if __name__ == '__main__': 35 | nums = [1, 2, 3, 1, 1, 3] 36 | nums = [1, 1, 1, 1] 37 | print(Solution().numIdenticalPairs(nums)) 38 | -------------------------------------------------------------------------------- /episode49-2021-06-17/q1769-minimum-number-of-operations-to-move-all-balls-to-each-box.py: -------------------------------------------------------------------------------- 1 | class Solution: # O(n**2) 2 | def minOperations(self, boxes: str) -> list[int]: 3 | answers = [] 4 | n = len(boxes) 5 | for i in range(n): 6 | op = 0 7 | for j in range(n): 8 | if boxes[j] == '1': 9 | op = op + abs(i - j) 10 | answers.append(op) 11 | return answers 12 | 13 | 14 | class Solution: # O(n) 15 | def minOperations(self, boxes: str) -> list[int]: 16 | n = len(boxes) 17 | answer = [0] * n 18 | curr, steps = 0, 0 19 | for i in range(n): 20 | answer[i] += steps 21 | curr += int(boxes[i]) 22 | steps += curr 23 | curr, steps = 0, 0 24 | for i in reversed(range(n)): 25 | answer[i] += steps 26 | curr += int(boxes[i]) 27 | steps += curr 28 | return answer 29 | 30 | 31 | if __name__ == '__main__': 32 | boxes = "110" 33 | print(Solution().minOperations(boxes)) 34 | -------------------------------------------------------------------------------- /episode39-2021-05-13/q1672_richest_customer_wealth.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maximumWealth(self, accounts: List[List[int]]) -> int: 6 | wealth = [] 7 | for account in accounts: 8 | s = 0 9 | for bank in account: 10 | s = s + bank 11 | wealth.append(s) 12 | 13 | cur_max = wealth[0] 14 | for w in wealth[1:]: 15 | if w > cur_max: 16 | cur_max = w 17 | 18 | return cur_max 19 | 20 | def maximum_wealth(self, accounts): 21 | return max([sum(acc) for acc in accounts]) 22 | 23 | def maximum_wealth_ef(self, accounts): 24 | cur_max = float('-inf') 25 | for account in accounts: 26 | s = 0 27 | for bank in account: 28 | s = s + bank 29 | 30 | if s > cur_max: 31 | cur_max = s 32 | 33 | return cur_max 34 | 35 | 36 | if __name__ == '__main__': 37 | accounts = [[1, 5], [7, 3], [3, 5]] 38 | 39 | print(Solution().maximum_wealth_ef(accounts)) 40 | -------------------------------------------------------------------------------- /episode35-2021-04-29/q1570_dot_product_of_two_sparse_vectors.py: -------------------------------------------------------------------------------- 1 | class SparseVector: 2 | def __init__(self, nums): 3 | self.length = len(nums) 4 | self.sparse_dict = {} 5 | for i, el in enumerate(nums): 6 | if el: 7 | self.sparse_dict[i] = el 8 | 9 | # Return the dotProduct of two sparse vectors 10 | def dotProduct(self, vec): 11 | if self.length != vec.length: 12 | raise ValueError('Vectors should have equal length') 13 | 14 | s = 0 15 | for key in self.sparse_dict: 16 | if key in vec.sparse_dict: 17 | s += self.sparse_dict[key] * vec.sparse_dict[key] 18 | return s 19 | 20 | 21 | # Your SparseVector object will be instantiated and called as such: 22 | # v1 = SparseVector(nums1) 23 | # v2 = SparseVector(nums2) 24 | # ans = v1.dotProduct(v2) 25 | 26 | if __name__ == '__main__': 27 | nums1 = [1, 0, 2] 28 | nums2 = [0, 2, 3] 29 | 30 | sv1 = SparseVector(nums1) 31 | sv2 = SparseVector(nums2) 32 | # print(sv1.sparse_dict) 33 | # print(sv2.sparse_dict) 34 | print(sv1.dotProduct(sv2)) 35 | -------------------------------------------------------------------------------- /episode63-2021-08-05/q1282.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import OrderedDict 3 | 4 | 5 | class Solution: 6 | def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]: 7 | groups = sorted(list(set(groupSizes))) 8 | 9 | group_dict = OrderedDict() 10 | for group in groups: 11 | if group in group_dict: 12 | pass 13 | else: 14 | group_dict[group] = [] 15 | 16 | for i, gs in enumerate(groupSizes): 17 | group_dict[gs].append(i) 18 | 19 | list_of_groups = [] 20 | for gs, elements in group_dict.items(): 21 | n = len(elements) 22 | l = [] 23 | i = 0 24 | while i < n: 25 | if len(l) < gs: 26 | l.append(elements[i]) 27 | else: 28 | list_of_groups.append(l) 29 | i = i - 1 30 | l = [] 31 | i = i + 1 32 | 33 | list_of_groups.append(l) 34 | 35 | return list_of_groups 36 | 37 | 38 | if __name__ == '__main__': 39 | groupSizes = [3, 3, 3, 3, 3, 1, 3] 40 | print(Solution().groupThePeople(groupSizes)) 41 | -------------------------------------------------------------------------------- /episode39-2021-05-13/q1431_kids_with_the_greatest_number_of_candies.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def kidsWithCandies(self, candies: List[int], extraCandies: int) -> List[bool]: 6 | 7 | max_true = [] 8 | 9 | for i in range(len(candies)): 10 | candies_copy = candies.copy() 11 | candies_copy[i] = candies_copy[i] + extraCandies 12 | 13 | cur_max = candies_copy[0] 14 | for kid in candies_copy[1:]: 15 | if kid > cur_max: 16 | cur_max = kid 17 | 18 | max_indexes = [] 19 | for k in range(len(candies_copy)): 20 | if candies_copy[k] == cur_max: 21 | max_indexes.append(k) 22 | 23 | if i in max_indexes: 24 | max_true.append(True) 25 | else: 26 | max_true.append(False) 27 | 28 | return max_true 29 | 30 | def kids_with_candies(self, candies, extraCandies): 31 | max_el = max(candies) 32 | 33 | for i in range(len(candies)): 34 | candies[i] = (candies[i] - max_el + extraCandies) >= 0 35 | 36 | return candies 37 | 38 | def kids_with_candies_one_on2(self, candies, extraCandies): 39 | return [el + extraCandies >= max(candies) for el in candies] 40 | 41 | def kids_with_candies_one_on(self, candies: List[int], extraCandies: int) -> List[bool]: 42 | max_el = max(candies) 43 | return [el + extraCandies >= max_el for el in candies] 44 | 45 | 46 | if __name__ == '__main__': 47 | candies = [2, 3, 5, 1, 3] 48 | delta = [-3, -2, 0, -4, -2] 49 | extraCandies = 3 50 | 51 | print(Solution().kids_with_candies_one(candies, extraCandies)) 52 | -------------------------------------------------------------------------------- /episode71-2021-09-09/q1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def twoSum(self, nums: List[int], target: int) -> List[int]: 6 | n = len(nums) 7 | # O(n) 8 | nums_ind = [(nums[i], i) for i in range(n)] 9 | 10 | # O(nlog(n)) 11 | nums_sorted = sorted(nums_ind, key=lambda tup: tup[0]) 12 | 13 | # O(nlog(n)) 14 | for i in range(n): 15 | compliment = target - nums_sorted[i][0] 16 | compliment_index = self.bs(nums_sorted, 0, n - 1, compliment) 17 | 18 | if compliment_index is not None and compliment_index != i: 19 | return [nums_sorted[i][1], 20 | nums_sorted[compliment_index][1]] 21 | 22 | def bs(self, arr, start, end, target): 23 | # base case 24 | if end <= start: 25 | if arr[start][0] == target: 26 | return start 27 | return 28 | 29 | # recursive case 30 | mid = start + ((end - start) // 2) 31 | if target == arr[mid][0]: 32 | return mid 33 | elif target < arr[mid][0]: 34 | return self.bs(arr, start, mid - 1, target) 35 | elif target > arr[mid][0]: 36 | return self.bs(arr, mid + 1, end, target) 37 | 38 | 39 | class Solution: 40 | def twoSum(self, nums: List[int], target: int) -> List[int]: 41 | n = len(nums) 42 | d = {} 43 | for i in range(n): 44 | compliment = target - nums[i] 45 | if nums[i] in d: 46 | return [i, d[nums[i]]] 47 | else: 48 | d[compliment] = i 49 | 50 | 51 | if __name__ == '__main__': 52 | nums = [2, 7, 11, 15] 53 | target = 9 54 | print(Solution().twoSum(nums, target)) 55 | -------------------------------------------------------------------------------- /episode41-2021-05-18/sorting.py: -------------------------------------------------------------------------------- 1 | def bubble_sort(arr): 2 | # O(n**2) 3 | swapped = False 4 | for i in range(len(arr)): 5 | for j in range(len(arr) - 1 - i): 6 | if arr[j] > arr[j + 1]: 7 | arr[j], arr[j + 1] = arr[j + 1], arr[j] 8 | swapped = True 9 | if not swapped: 10 | break 11 | 12 | 13 | def selection_sort(arr): 14 | # O(n**2) 15 | for i in range(len(arr)): 16 | min_index = i 17 | for j in range(i + 1, len(arr)): 18 | if arr[j] < arr[min_index]: 19 | min_index = j 20 | arr[i], arr[min_index] = arr[min_index], arr[i] 21 | 22 | 23 | def insertion_sort(arr): 24 | # O(n**2) 25 | for i in range(1, len(arr)): 26 | j = i - 1 27 | cur_el = arr[i] 28 | while j >= 0 and cur_el < arr[j]: 29 | arr[j + 1] = arr[j] 30 | j = j - 1 31 | arr[j + 1] = cur_el # insert 32 | 33 | 34 | def quick_sort_op(arr): 35 | if len(arr) < 2: 36 | return arr 37 | 38 | pivot = arr[-1] 39 | 40 | less = [el for el in arr[:-1] if el < pivot] 41 | greater = [el for el in arr[:-1] if el >= pivot] 42 | 43 | return quick_sort_op(less) + [pivot] + quick_sort_op(greater) 44 | 45 | 46 | def partition(arr, start, end): 47 | i = start - 1 48 | pivot = arr[end] 49 | for j in range(start, end): 50 | if arr[j] < pivot: 51 | i = i + 1 52 | arr[i], arr[j] = arr[j], arr[i] 53 | arr[i + 1], arr[end] = arr[end], arr[i + 1] 54 | return i + 1 55 | 56 | 57 | def quick_sort(arr, start, end): 58 | if start < end: 59 | pi = partition(arr, start, end) 60 | quick_sort(arr, start, pi - 1) 61 | quick_sort(arr, pi + 1, end) 62 | 63 | 64 | if __name__ == '__main__': 65 | nums = [4, 8, 2, 1, 3] 66 | quick_sort(nums, 0, len(nums) - 1) 67 | print(nums) 68 | -------------------------------------------------------------------------------- /episode72-2021-09-16/q121.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | # brute force O(n**2) 5 | class Solution: 6 | def maxProfit(self, prices: List[int]) -> int: 7 | if len(prices) < 2: 8 | return 0 9 | 10 | n = len(prices) 11 | deals = [] 12 | for i in range(n): 13 | for j in range(i + 1, n): 14 | deals.append(prices[j] - prices[i]) 15 | return max(max(deals), 0) 16 | 17 | 18 | # O(n**2) 19 | class Solution: 20 | def maxProfit(self, prices: List[int]) -> int: 21 | 22 | while len(prices) > 1: 23 | # O(n) 24 | min_el = min(prices) 25 | max_el = max(prices) 26 | 27 | # O(n) 28 | min_el_ind = prices.index(min_el) 29 | max_el_ind = prices.index(max_el) 30 | 31 | if max_el_ind > min_el_ind: 32 | return max_el - min_el 33 | else: 34 | # O(n) 35 | del prices[max_el_ind] 36 | 37 | return 0 38 | 39 | 40 | class Solution: 41 | def maxProfit(self, prices: List[int]) -> int: 42 | if len(prices) < 2: 43 | return 0 44 | 45 | n = len(prices) 46 | i = 0 47 | j = 1 48 | cur_max = prices[j] - prices[i] 49 | while i < j < n and i < n: 50 | if prices[j] <= prices[i]: 51 | j = j + 1 52 | i = i + 1 53 | else: 54 | cur = prices[j] - prices[i] 55 | if cur > cur_max: 56 | cur_max = cur 57 | j = j + 1 58 | return cur_max 59 | 60 | 61 | class Solution: 62 | def maxProfit(self, prices): 63 | max_profit, min_price = 0, float('inf') 64 | for price in prices: 65 | min_price = min(min_price, price) 66 | profit = price - min_price 67 | max_profit = max(max_profit, profit) 68 | return max_profit 69 | 70 | 71 | if __name__ == '__main__': 72 | prices = [7, 1, 5, 3, 6, 4] 73 | print(Solution().maxProfit(prices)) 74 | -------------------------------------------------------------------------------- /episode33-2021-04-22/q1265_print_linked_list_in_reverse.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, data): 3 | self.data = data 4 | self.next = None 5 | 6 | def getNext(self): 7 | return self.next 8 | 9 | def printValue(self): 10 | print(self.data) 11 | 12 | def __repr__(self): 13 | return str(self.data) 14 | 15 | 16 | class LinkedList: 17 | def __init__(self, node): 18 | self.head = node 19 | 20 | def insert_at_beginning(self, node): 21 | node.next = self.head 22 | self.head = node 23 | 24 | def __repr__(self): 25 | s = '' 26 | tmp = self.head 27 | while tmp: 28 | s = s + str(tmp.data) + '-->' 29 | tmp = tmp.next 30 | return s 31 | 32 | def get_arr(self): 33 | arr = [] 34 | tmp = self.head 35 | while tmp: 36 | arr.append(tmp) 37 | tmp = tmp.next 38 | return arr 39 | 40 | 41 | ll = LinkedList(Node(1)) 42 | ll.insert_at_beginning(Node(2)) 43 | ll.insert_at_beginning(Node(3)) 44 | 45 | 46 | def print_in_reverse(head): 47 | arr = [] 48 | tmp = head 49 | while tmp: 50 | arr.append(tmp) 51 | tmp = tmp.getNext() 52 | 53 | for el in arr[::-1]: 54 | el.printValue() 55 | 56 | 57 | def print_in_reverse_rec(head): 58 | next = head.getNext() 59 | 60 | if not next: 61 | head.printValue() 62 | return 63 | else: 64 | print_in_reverse_rec(next) 65 | 66 | head.printValue() 67 | return 68 | 69 | 70 | # print_in_reverse_rec(ll.head) 71 | 72 | arr = [1, 2, 3] 73 | 74 | 75 | def print_for_loop(arr): 76 | for i in range(len(arr)): 77 | print(arr[i]) 78 | 79 | 80 | def print_for_loop_rec(arr): 81 | if len(arr) < 1: 82 | return 83 | print(arr[0]) 84 | print_for_loop_rec(arr[1:]) 85 | 86 | 87 | def get_max(arr): 88 | max = arr[0] 89 | for i in range(1, len(arr)): 90 | if arr[i] > max: 91 | max = arr[i] 92 | return max 93 | 94 | 95 | def get_max_rec(arr): 96 | if len(arr) <= 1: 97 | return arr 98 | 99 | if len(arr) == 2: 100 | return arr[0] if arr[0] > arr[1] else arr[1] 101 | 102 | sub_max = get_max_rec(arr[1:]) 103 | 104 | return arr[0] if arr[0] > sub_max else sub_max 105 | 106 | 107 | # wimp solution 108 | def Max(list): 109 | if len(list) == 1: 110 | return list[0] 111 | else: 112 | m = Max(list[1:]) 113 | return m if m > list[0] else list[0] 114 | 115 | 116 | arr = [1] 117 | print(Max(arr)) 118 | -------------------------------------------------------------------------------- /episode67-2021-08-19/q938.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from collections import deque 3 | from math import floor 4 | 5 | 6 | class TreeNode: 7 | def __init__(self, val=0, left=None, right=None): 8 | self.val = val 9 | self.left = left 10 | self.right = right 11 | 12 | def __repr__(self): 13 | return str(self.val) 14 | 15 | 16 | # geeks for geeks 17 | def buildTree(ip): 18 | # Create the root of the tree 19 | root = TreeNode(int(ip[0])) 20 | size = 0 21 | q = deque() 22 | 23 | # Push the root to the queue 24 | q.append(root) 25 | size = size + 1 26 | 27 | # Starting from the second element 28 | i = 1 29 | while (size > 0 and i < len(ip)): 30 | # Get and remove the front of the queue 31 | currNode = q[0] 32 | q.popleft() 33 | size = size - 1 34 | 35 | # Get the current node's value from the string 36 | currVal = ip[i] 37 | 38 | # If the left child is not null 39 | if (currVal != "N"): 40 | # Create the left child for the current node 41 | currNode.left = TreeNode(int(currVal)) 42 | 43 | # Push it to the queue 44 | q.append(currNode.left) 45 | size = size + 1 46 | # For the right child 47 | i = i + 1 48 | if (i >= len(ip)): 49 | break 50 | currVal = ip[i] 51 | 52 | # If the right child is not null 53 | if (currVal != "N"): 54 | # Create the right child for the current node 55 | currNode.right = TreeNode(int(currVal)) 56 | 57 | # Push it to the queue 58 | q.append(currNode.right) 59 | size = size + 1 60 | i = i + 1 61 | return root 62 | 63 | 64 | def print_tree(node, level=0): 65 | if node is not None: 66 | print_tree(node.right, level=level + 1) 67 | print(3 * ' ' * level + str(node.val)) 68 | print_tree(node.left, level=level + 1) 69 | 70 | 71 | def print_tree1(node): 72 | if node is not None: 73 | print_tree1(node.left) 74 | print(str(node.val)) 75 | print_tree1(node.right) 76 | 77 | 78 | class Solution: 79 | 80 | def __init__(self): 81 | self.sum_range = 0 82 | 83 | def rangeSumBST(self, root: Optional[TreeNode], low: int, high: int) -> int: 84 | 85 | self.sum_range = 0 86 | 87 | def _inorder_traversal(node): 88 | if node is not None: 89 | _inorder_traversal(node.left) 90 | if low <= node.val <= high: 91 | self.sum_range += node.val 92 | _inorder_traversal(node.right) 93 | 94 | _inorder_traversal(root) 95 | return self.sum_range 96 | 97 | 98 | if __name__ == '__main__': 99 | tree_array = [10, 5, 15, 3, 7, 'N', 18] 100 | low = 7 101 | high = 15 102 | root = buildTree(tree_array) 103 | print_tree(root) 104 | print(Solution().rangeSumBST(root, low, high)) 105 | -------------------------------------------------------------------------------- /episode70-2021-09-02/q1038.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class TreeNode: 5 | def __init__(self, val=0, left=None, right=None): 6 | self.val = val 7 | self.left = left 8 | self.right = right 9 | 10 | def __repr__(self): 11 | return str(self.val) 12 | 13 | 14 | # geeks for geeks 15 | def buildTree(ip): 16 | # Create the root of the tree 17 | root = TreeNode(int(ip[0])) 18 | size = 0 19 | q = deque() 20 | 21 | # Push the root to the queue 22 | q.append(root) 23 | size = size + 1 24 | 25 | # Starting from the second element 26 | i = 1 27 | while (size > 0 and i < len(ip)): 28 | # Get and remove the front of the queue 29 | currNode = q[0] 30 | q.popleft() 31 | size = size - 1 32 | 33 | # Get the current node's value from the string 34 | currVal = ip[i] 35 | 36 | # If the left child is not null 37 | if (currVal != "N"): 38 | # Create the left child for the current node 39 | currNode.left = TreeNode(int(currVal)) 40 | 41 | # Push it to the queue 42 | q.append(currNode.left) 43 | size = size + 1 44 | # For the right child 45 | i = i + 1 46 | if (i >= len(ip)): 47 | break 48 | currVal = ip[i] 49 | 50 | # If the right child is not null 51 | if (currVal != "N"): 52 | # Create the right child for the current node 53 | currNode.right = TreeNode(int(currVal)) 54 | 55 | # Push it to the queue 56 | q.append(currNode.right) 57 | size = size + 1 58 | i = i + 1 59 | return root 60 | 61 | 62 | def print_tree(node, level=0): 63 | if node is not None: 64 | print_tree(node.right, level=level + 1) 65 | print(3 * ' ' * level + str(node.val)) 66 | print_tree(node.left, level=level + 1) 67 | 68 | 69 | class Solution: 70 | def bstToGst(self, root: TreeNode) -> TreeNode: 71 | 72 | self.inorder = [] 73 | 74 | # O(n) 75 | def _inorder_traversal(node): 76 | if node is not None: 77 | _inorder_traversal(node.left) 78 | self.inorder.append(node) 79 | _inorder_traversal(node.right) 80 | 81 | _inorder_traversal(root) 82 | 83 | # O(n) 84 | n = len(self.inorder) 85 | cur = self.inorder[-1].val 86 | cumsum = [cur] 87 | for i in range(n - 2, -1, -1): 88 | cur = cur + self.inorder[i].val 89 | cumsum.append(cur) 90 | 91 | # O(n) 92 | for i, node in enumerate(self.inorder): 93 | node.val = node.val + cumsum[n - 1 - i] 94 | 95 | return root 96 | 97 | 98 | if __name__ == '__main__': 99 | root_arr = [4, 1, 6, 0, 2, 5, 7, 'N', 'N', 'N', 3, 'N', 'N', 'N', 8] 100 | root = buildTree(root_arr) 101 | print_tree(root) 102 | print(Solution().bstToGst(root)) 103 | print_tree(root) 104 | -------------------------------------------------------------------------------- /episode57-2021-07-15/q1379.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class TreeNode: 5 | def __init__(self, val=0, left=None, right=None): 6 | self.val = val 7 | self.left = left 8 | self.right = right 9 | 10 | def __repr__(self): 11 | return str(self.val) 12 | 13 | 14 | # geeks for geeks 15 | def buildTree(ip): 16 | # Create the root of the tree 17 | root = TreeNode(int(ip[0])) 18 | size = 0 19 | q = deque() 20 | 21 | # Push the root to the queue 22 | q.append(root) 23 | size = size + 1 24 | 25 | # Starting from the second element 26 | i = 1 27 | while (size > 0 and i < len(ip)): 28 | # Get and remove the front of the queue 29 | currNode = q[0] 30 | q.popleft() 31 | size = size - 1 32 | 33 | # Get the current node's value from the string 34 | currVal = ip[i] 35 | 36 | # If the left child is not null 37 | if (currVal != "N"): 38 | # Create the left child for the current node 39 | currNode.left = TreeNode(int(currVal)) 40 | 41 | # Push it to the queue 42 | q.append(currNode.left) 43 | size = size + 1 44 | # For the right child 45 | i = i + 1 46 | if (i >= len(ip)): 47 | break 48 | currVal = ip[i] 49 | 50 | # If the right child is not null 51 | if (currVal != "N"): 52 | # Create the right child for the current node 53 | currNode.right = TreeNode(int(currVal)) 54 | 55 | # Push it to the queue 56 | q.append(currNode.right) 57 | size = size + 1 58 | i = i + 1 59 | return root 60 | 61 | 62 | def print_tree(node, level=0): 63 | if node is not None: 64 | print_tree(node.right, level=level + 1) 65 | print(3 * ' ' * level + str(node.val)) 66 | print_tree(node.left, level=level + 1) 67 | 68 | 69 | class Solution: 70 | def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode: 71 | inorder = [] 72 | stack = [] 73 | cur = cloned 74 | while True: 75 | if cur is not None: 76 | stack.append(cur) 77 | cur = cur.left 78 | elif len(stack) > 0: 79 | new_cur = stack.pop() 80 | inorder.append(new_cur) 81 | cur = new_cur.right 82 | else: 83 | break 84 | 85 | return inorder 86 | 87 | 88 | class Solution: 89 | def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode: 90 | inorder = [] 91 | stack = [] 92 | cur = cloned 93 | while True: 94 | if cur is not None: 95 | stack.append(cur) 96 | cur = cur.left 97 | elif len(stack) > 0: 98 | new_cur = stack.pop() 99 | if new_cur.val == target.val: 100 | return new_cur 101 | inorder.append(new_cur) 102 | cur = new_cur.right 103 | else: 104 | break 105 | 106 | return inorder 107 | 108 | 109 | if __name__ == '__main__': 110 | tree = [7, 4, 3, 'N', 'N', 6, 19] 111 | original = buildTree(tree) 112 | cloned = buildTree(tree) 113 | target = original.right 114 | Solution().getTargetCopy(original, cloned, target) 115 | -------------------------------------------------------------------------------- /episode53-2021-07-01/q1302.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class TreeNode: 5 | def __init__(self, val=0, left=None, right=None): 6 | self.val = val 7 | self.left = left 8 | self.right = right 9 | 10 | def __repr__(self): 11 | return str(self.val) 12 | 13 | 14 | class Solution: 15 | 16 | def get_max_depth(self, root): 17 | 18 | global max_depth 19 | 20 | max_depth = 0 21 | 22 | def _get_max_depth(node, level=0): 23 | global max_depth 24 | if node is not None: 25 | 26 | _get_max_depth(node.right, level=level + 1) 27 | if level > max_depth: 28 | max_depth = level 29 | _get_max_depth(node.left, level=level + 1) 30 | 31 | _get_max_depth(root) 32 | 33 | return max_depth 34 | 35 | def deepestLeavesSum(self, root: TreeNode) -> int: 36 | global max_depth 37 | global sum_max_depth 38 | 39 | max_depth = self.get_max_depth(root) 40 | sum_max_depth = 0 41 | 42 | def _traverse(node, level=0): 43 | global max_depth 44 | global sum_max_depth 45 | 46 | if node is not None: 47 | 48 | _traverse(node.right, level=level + 1) 49 | if level == max_depth: 50 | sum_max_depth = sum_max_depth + node.val 51 | _traverse(node.left, level=level + 1) 52 | 53 | _traverse(root) 54 | 55 | return sum_max_depth 56 | 57 | 58 | # Function to Build Tree 59 | def buildTree(ip): 60 | # Create the root of the tree 61 | root = TreeNode(int(ip[0])) 62 | size = 0 63 | q = deque() 64 | 65 | # Push the root to the queue 66 | q.append(root) 67 | size = size + 1 68 | 69 | # Starting from the second element 70 | i = 1 71 | while (size > 0 and i < len(ip)): 72 | # Get and remove the front of the queue 73 | currNode = q[0] 74 | q.popleft() 75 | size = size - 1 76 | 77 | # Get the current node's value from the string 78 | currVal = ip[i] 79 | 80 | # If the left child is not null 81 | if (currVal != "N"): 82 | # Create the left child for the current node 83 | currNode.left = TreeNode(int(currVal)) 84 | 85 | # Push it to the queue 86 | q.append(currNode.left) 87 | size = size + 1 88 | # For the right child 89 | i = i + 1 90 | if (i >= len(ip)): 91 | break 92 | currVal = ip[i] 93 | 94 | # If the right child is not null 95 | if (currVal != "N"): 96 | # Create the right child for the current node 97 | currNode.right = TreeNode(int(currVal)) 98 | 99 | # Push it to the queue 100 | q.append(currNode.right) 101 | size = size + 1 102 | i = i + 1 103 | return root 104 | 105 | 106 | def print_tree(node, level=0): 107 | if node is not None: 108 | print_tree(node.right, level=level + 1) 109 | print(3 * ' ' * level + str(node.val)) 110 | print_tree(node.left, level=level + 1) 111 | 112 | 113 | if __name__ == '__main__': 114 | nodes = [1, 2, 3, 4, 5, 'N', 6, 7, 'N', 'N', 'N', 'N', 8] 115 | nodes = [6, 7, 8, 2, 7, 1, 3, 9, 'N', 1, 4, 'N', 'N', 'N', 5] 116 | root = buildTree(nodes) 117 | 118 | print_tree(root) 119 | 120 | print(Solution().get_max_depth(root)) 121 | print(Solution().deepestLeavesSum(root)) 122 | -------------------------------------------------------------------------------- /episode61-2021-07-29/q1315.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | from math import floor 3 | 4 | 5 | class TreeNode: 6 | def __init__(self, val=0, left=None, right=None): 7 | self.val = val 8 | self.left = left 9 | self.right = right 10 | 11 | def __repr__(self): 12 | return str(self.val) 13 | 14 | 15 | # geeks for geeks 16 | def buildTree(ip): 17 | # Create the root of the tree 18 | root = TreeNode(int(ip[0])) 19 | size = 0 20 | q = deque() 21 | 22 | # Push the root to the queue 23 | q.append(root) 24 | size = size + 1 25 | 26 | # Starting from the second element 27 | i = 1 28 | while (size > 0 and i < len(ip)): 29 | # Get and remove the front of the queue 30 | currNode = q[0] 31 | q.popleft() 32 | size = size - 1 33 | 34 | # Get the current node's value from the string 35 | currVal = ip[i] 36 | 37 | # If the left child is not null 38 | if (currVal != "N"): 39 | # Create the left child for the current node 40 | currNode.left = TreeNode(int(currVal)) 41 | 42 | # Push it to the queue 43 | q.append(currNode.left) 44 | size = size + 1 45 | # For the right child 46 | i = i + 1 47 | if (i >= len(ip)): 48 | break 49 | currVal = ip[i] 50 | 51 | # If the right child is not null 52 | if (currVal != "N"): 53 | # Create the right child for the current node 54 | currNode.right = TreeNode(int(currVal)) 55 | 56 | # Push it to the queue 57 | q.append(currNode.right) 58 | size = size + 1 59 | i = i + 1 60 | return root 61 | 62 | 63 | def print_tree(node, level=0): 64 | if node is not None: 65 | print_tree(node.right, level=level + 1) 66 | print(3 * ' ' * level + str(node.val)) 67 | print_tree(node.left, level=level + 1) 68 | 69 | 70 | class Solution: 71 | def sumEvenGrandparent(self, root: TreeNode) -> int: 72 | level_order = self.printLevelOrder(root) 73 | answer = 0 74 | 75 | for i in range(len(level_order)): 76 | parent = (i - 1) // 2 77 | grandparent = (parent - 1) // 2 78 | 79 | print(level_order[i], parent, grandparent) 80 | 81 | if grandparent >= 0 and level_order[grandparent] != 'N' \ 82 | and level_order[grandparent] % 2 == 0: 83 | if level_order[i] != 'N': 84 | answer += level_order[i] 85 | print(level_order) 86 | return answer 87 | 88 | def printLevelOrder(self, root): 89 | # Base Case 90 | if root is None: 91 | return 92 | 93 | # Create an empty queue 94 | # for level order traversal 95 | queue = [] 96 | 97 | # Enqueue Root and initialize height 98 | queue.append(root) 99 | 100 | level_order = [] 101 | 102 | while (len(queue) > 0): 103 | 104 | # Print front of queue and 105 | # remove it from queue 106 | # print(queue[0].val) 107 | if queue[0] == 'N': 108 | level_order.append('N') 109 | queue.pop(0) 110 | continue 111 | 112 | if queue[0].val is not None: 113 | level_order.append(queue[0].val) 114 | 115 | node = queue.pop(0) 116 | 117 | # Enqueue left child 118 | if node.left is not None: 119 | queue.append(node.left) 120 | else: 121 | queue.append("N") 122 | 123 | # Enqueue right child 124 | if node.right is not None: 125 | queue.append(node.right) 126 | else: 127 | queue.append("N") 128 | 129 | return level_order 130 | 131 | 132 | if __name__ == '__main__': 133 | tree_repr = [50, 'N', 54, 98, 6, 'N', 'N', 'N', 34] 134 | root = buildTree(tree_repr) 135 | print_tree(root) 136 | print(Solution().sumEvenGrandparent(root)) 137 | --------------------------------------------------------------------------------