diff --git a/.github/ISSUE_TEMPLATE/submit-a-leetcode-problem.md b/.github/ISSUE_TEMPLATE/submit-a-leetcode-problem.md index fa91559..8d05d3b 100644 --- a/.github/ISSUE_TEMPLATE/submit-a-leetcode-problem.md +++ b/.github/ISSUE_TEMPLATE/submit-a-leetcode-problem.md @@ -2,7 +2,7 @@ name: Submit a LeetCode Problem about: Use this Template to submit a new LeetCode Problem title: 00## - LeetCode Problem Title -labels: 'hacktoberfest, help wanted, good first issue' +labels: 'hacktoberfest' assignees: '' --- diff --git a/.github/workflows/leetcodeChecker.yml b/.github/workflows/leetcodeChecker.yml new file mode 100644 index 0000000..2ca45a3 --- /dev/null +++ b/.github/workflows/leetcodeChecker.yml @@ -0,0 +1,30 @@ +name: py + +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@v2 + - name: setup python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: run python + run: | + python leetcodeChecker.py + env: + GITHUB_ACCESS_TOKEN: ${{ github.TOKEN }} + REPO_NAME: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} + LEETCODE_CSRF_TOKEN: ${{ secrets.LEETCODE_CSRF_TOKEN }} + LEETCODE_SESSION_TOKEN: ${{ secrets.LEETCODE_SESSION }} + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a64b946..04b4a9a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,10 +12,10 @@ The Contributer who opened an issue will be assigned prefered to the issue. If t ### Pull Requests Only Pull Requests **joined with an Issue** and matching the **naming-conventions** (See Folders and Files) will be merged! If there is no Issue joined in the PR your PR will be labeld as **spam** and closed. -If your code don't passes the Check on LeetCode.com your PR will be labeld as **"invalid"** and the Issue stays open for the next PR! +If your code don't passes the Check on LeetCode.com your PR will be labled as **"invalid"** and the Issue stays open for the next PR! If your PR doesn' follow the Contributing Guidelines of this Repository it will be also marked as **spam** and closed! -## Which PR will be accepted? +## Which PR's will be accepted? * Ones you are assigned to * Your PR has to link the Issue * Your Solution must be correct - you can check ist on LeetCode (submit) if it works on different test-cases diff --git a/LeetCode/0006_ZigZag_Conversion.py b/LeetCode/0006_ZigZag_Conversion.py new file mode 100644 index 0000000..ab9f2c0 --- /dev/null +++ b/LeetCode/0006_ZigZag_Conversion.py @@ -0,0 +1,21 @@ +class Solution: + # @param {string} s + # @param {integer} numRows + # @return {string} + def convert(self, s, numRows): + + if numRows == 1: + return s + + rows = ["" for i in range(numRows)] + + direction = -1 + row = 0 + for i in range(len(s)): + + rows[row]+=s[i] + if (row == 0 or row==numRows-1): + direction *= -1 + row+=direction + + return "".join(rows) diff --git a/LeetCode/0010_Regular_Expression_Matching.py b/LeetCode/0010_Regular_Expression_Matching.py new file mode 100644 index 0000000..3f97e39 --- /dev/null +++ b/LeetCode/0010_Regular_Expression_Matching.py @@ -0,0 +1,20 @@ +class Solution: + def isMatch(self, s: str, p: str) -> bool: + string, pattern = [], [] + string[:0], pattern[:0] = s, p + string.insert(0, 0) + pattern.insert(0, 0) + s, p = len(string), len(pattern) + dp = [[False for _ in range(p)] for __ in range(s)] + dp[0][0] = True + for i in range(p): + if pattern[i] is '*' and dp[0][i-2]: dp[0][i] = True + for i in range(1, s): + for j in range(1, p): + if pattern[j] is string[i] or pattern[j] is '.': + dp[i][j] = dp[i-1][j-1] + elif pattern[j] is '*' and (pattern[j-1] is string[i] or pattern[j-1] is '.'): + dp[i][j] = dp[i][j-2] or dp[i-1][j] + elif pattern[j] is '*' and not (pattern[j-1] is string[i] or pattern[j-1] is '.'): + dp[i][j] = dp[i][j-2] + return dp[s-1][p-1] diff --git a/LeetCode/0013_Roman to Integer.py b/LeetCode/0013_Roman to Integer.py new file mode 100644 index 0000000..7ec9c38 --- /dev/null +++ b/LeetCode/0013_Roman to Integer.py @@ -0,0 +1,32 @@ +class Solution: + def romanToInt(self, s: str) -> int: + + symbolValDict = { + 'I':1, + 'V':5, + 'X':10, + 'L':50, + 'C':100, + 'D':500, + 'M':1000 + } + + + i = 0 + finalDigit = 0 + while(i= nextDigit: + finalDigit += firstDigit + i+=1 + else: + finalDigit += nextDigit - firstDigit + i+=2 + else: + finalDigit += firstDigit + i+=1 + + + return finalDigit \ No newline at end of file diff --git a/LeetCode/0014_Longest_common_Prefix.py b/LeetCode/0014_Longest_common_Prefix.py new file mode 100644 index 0000000..de0859d --- /dev/null +++ b/LeetCode/0014_Longest_common_Prefix.py @@ -0,0 +1,16 @@ +class Solution: + def longestCommonPrefix(self, strs): + """ + :type strs: List[str] + :rtype: str + """ + if len(strs) == 0: + return '' + res = '' + strs = sorted(strs) + for i in strs[0]: + if strs[-1].startswith(res+i): + res += i + else: + break + return res \ No newline at end of file diff --git a/LeetCode/0022_GenerateParenthesis.py b/LeetCode/0022_GenerateParenthesis.py new file mode 100644 index 0000000..0954aca --- /dev/null +++ b/LeetCode/0022_GenerateParenthesis.py @@ -0,0 +1,25 @@ +class Solution: + def generateParenthesis(self, n: int) -> List[str]: + def isValid(s: str) -> bool: + stk = [] + for b in s: + if b == '(': + stk.append(b) + else: + if stk and stk[-1] == '(': + stk.pop() + else: + return False + return stk == [] + + ans = [] + for mask in range(1<<(2*n)): + s = "" + for bit in range(2*n): + if mask & (1<=m: + if haystack[i] == needle[j]: + temp = i + while j bool: + return self.isValidRow(board) and self.isValidCol(board) and self.isValidSquare(board) + + def isValidRow(self, board): + for row in board: + if not self.isValidUnit(row): + return False + return True + + def isValidCol(self, board): + for col in zip(*board): + if not self.isValidUnit(col): + return False + return True + + def isValidSquare(self, board): + for i in (0, 3, 6): + for j in (0, 3, 6): + square = [board[x][y] for x in range(i, i + 3) for y in range(j, j + 3)] + if not self.isValidUnit(square): + return False + return True + + def isValidUnit(self, unit): + array = [c for c in unit if c != '.'] + return len(set(array)) == len(array) \ No newline at end of file diff --git a/LeetCode/0043_Multiply Strings.py b/LeetCode/0043_Multiply Strings.py new file mode 100644 index 0000000..e6dd828 --- /dev/null +++ b/LeetCode/0043_Multiply Strings.py @@ -0,0 +1,7 @@ +class Solution(object): + def multiply(self, num1, num2): + a,b=eval(num1),eval(num2) + c=a*b + c=str(c) + return c + diff --git a/LeetCode/0047_Permutations II.py b/LeetCode/0047_Permutations II.py new file mode 100644 index 0000000..1039f98 --- /dev/null +++ b/LeetCode/0047_Permutations II.py @@ -0,0 +1,19 @@ +class Solution: + def permuteUnique(self, nums: List[int]) -> List[List[int]]: + results = [] + def Combination(permutation, counter): + if len(permutation) == len(nums): + results.append(list(permutation)) + return + + for num in counter: + if counter[num] > 0: + permutation.append(num) + counter[num] -= 1 + Combination(permutation, counter) + permutation.pop() + counter[num] += 1 + + Combination([], Counter(nums)) + + return results \ No newline at end of file diff --git a/LeetCode/0048_Rotate_Image.py b/LeetCode/0048_Rotate_Image.py new file mode 100644 index 0000000..918e60e --- /dev/null +++ b/LeetCode/0048_Rotate_Image.py @@ -0,0 +1,9 @@ +class Solution: + def rotate(self, matrix: List[List[int]]) -> None: + for i in range(len(matrix)): + for j in range(i,len(matrix)): + if i != j: + matrix[i][j],matrix[j][i]=matrix[j][i],matrix[i][j] + for each in matrix: + each.reverse() + return matrix \ No newline at end of file diff --git a/LeetCode/0051_N-Queen_1.py b/LeetCode/0051_N-Queen_1.py new file mode 100644 index 0000000..607be73 --- /dev/null +++ b/LeetCode/0051_N-Queen_1.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Oct 7 20:51:57 2020 + +@author: anjalisingh +""" + +class Solution(object): + def solveNQueens(self, n): + # i is column index + # left: left diagonal: \ level-i + # right: right diagonal: / level+i + self.col = [0]*n # not occupied column + self.left = [0]*(2*n-1) # number of left diagonal + self.right = [0]*(2*n-1) + board = [['.' for x in range(n)] for y in range(n)] + self.resultBoard = [] + self.backTrack(n, 0, board) + return self.resultBoard + + def backTrack(self, n, level, board): + if level == n: # finish + res = [] + for i in range(n): + res.append(''.join(board[i])) + self.resultBoard.append(res) + return + for i in range(n): # iterate every column + # if col, left, right are all not accupied, put a queue here + if not self.col[i] and not self.left[level-i] and not self.right[level+i]: + board[level][i] = 'Q' + self.col[i] = 1 + self.left[level-i] = 1 + self.right[level+i] = 1 # choose + self.backTrack(n, level+1, board) # explore + board[level][i] = '.' # un choose + self.col[i] = 0 + self.left[level-i] = 0 + self.right[level+i] = 0 + +# Queen = Solution() +# print(Queen.solveNQueens(4)) diff --git a/LeetCode/0052_N_Queens_2.py b/LeetCode/0052_N_Queens_2.py new file mode 100644 index 0000000..30b03d1 --- /dev/null +++ b/LeetCode/0052_N_Queens_2.py @@ -0,0 +1,13 @@ +class Solution(object): + # @return an integer + def totalNQueens(self, n): + return self.totalNQueensRecu([], 0, n) + + def totalNQueensRecu(self, solution, row, n): + if row == n: + return 1 + result = 0 + for i in xrange(n): + if i not in solution and reduce(lambda acc, j: abs(row - j) != abs(i - solution[j]) and acc, xrange(len(solution)), True): + result += self.totalNQueensRecu(solution + [i], row + 1, n) + return result \ No newline at end of file diff --git a/LeetCode/0055_jump_game.py b/LeetCode/0055_jump_game.py new file mode 100644 index 0000000..2b60469 --- /dev/null +++ b/LeetCode/0055_jump_game.py @@ -0,0 +1,12 @@ +from typing import List + + +class Solution: + def canJump(self, nums: List[int]) -> bool: + jump_length_left = 0 + for num in nums: + if jump_length_left == -1: + return False + jump_length_left = max(jump_length_left - 1, num - 1) + + return True diff --git a/LeetCode/0058_Length_of_Last_Word.py b/LeetCode/0058_Length_of_Last_Word.py new file mode 100644 index 0000000..db53f9f --- /dev/null +++ b/LeetCode/0058_Length_of_Last_Word.py @@ -0,0 +1,6 @@ +class Solution: + def lengthOfLastWord(self, s: str) -> int: + try: + return len(s.split()[-1]) + except IndexError: + return 0 diff --git a/LeetCode/0060 - Permutation_Sequence.py b/LeetCode/0060 - Permutation_Sequence.py new file mode 100644 index 0000000..d28e294 --- /dev/null +++ b/LeetCode/0060 - Permutation_Sequence.py @@ -0,0 +1,16 @@ +from itertools import permutations +class Solution: + data = [] + + def getPermutation(self, n: int, k: int) -> str: + self.data = [] + string = [] + for i in range(1, n+1): + string.append(str(i)) + string = list(permutations(string)) + temp = string[k-1] + string = [] + string.append("".join(temp)) + return string[0] + + diff --git a/LeetCode/0063_UniquePathsII.py b/LeetCode/0063_UniquePathsII.py new file mode 100644 index 0000000..3dbb6ef --- /dev/null +++ b/LeetCode/0063_UniquePathsII.py @@ -0,0 +1,22 @@ +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: + n, m = len(obstacleGrid), len(obstacleGrid[0]) + + ways = [[0 for j in range(m)] for i in range(n)] + + for i in range(n): + if obstacleGrid[i][0] == 1: + break + ways[i][0] = 1 + + for j in range(m): + if obstacleGrid[0][j] == 1: + break + ways[0][j] = 1 + + for i in range(1, n): + for j in range(1, m): + if obstacleGrid[i][j] == 0: + ways[i][j] = ways[i - 1][j] + ways[i][j - 1] + + return ways[n - 1][m - 1] diff --git a/LeetCode/0067_Add_Binary.py b/LeetCode/0067_Add_Binary.py new file mode 100644 index 0000000..529e8b1 --- /dev/null +++ b/LeetCode/0067_Add_Binary.py @@ -0,0 +1,4 @@ +class Solution: + def addBinary(self, a: str, b: str) -> str: + sum = int(a,2) + int(b,2) + return bin(sum)[2:] \ No newline at end of file diff --git a/LeetCode/0078_Subsets.py b/LeetCode/0078_Subsets.py new file mode 100644 index 0000000..23fccc3 --- /dev/null +++ b/LeetCode/0078_Subsets.py @@ -0,0 +1,21 @@ +#using backtracking approach + +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: + def backtrack(first = 0, curr = []): + # if the combination is done + if len(curr) == k: + output.append(curr[:]) + for i in range(first, n): + # add nums[i] into the current combination + curr.append(nums[i]) + # use next integers to complete the combination + backtrack(i + 1, curr) + # backtrack + curr.pop() + + output = [] + n = len(nums) + for k in range(n + 1): + backtrack() + return output diff --git a/LeetCode/0079_Word_Search.py b/LeetCode/0079_Word_Search.py new file mode 100644 index 0000000..82f56be --- /dev/null +++ b/LeetCode/0079_Word_Search.py @@ -0,0 +1,35 @@ +def exist(self, grid: List[List[str]], word: str) -> bool: + + seen = set() + + # Boundary checking + def inBound(row, col, grid): + return 0 <= row < len(grid) and 0 <= col < len(grid[0]) + + def dfs(grid, word, curr_i, row, col): + + if curr_i == len(word): + return True + + if not inBound(row, col,grid) or grid[row][col] != word[curr_i]: + return False + + seen.add((row, col)) + + # Explore possible paths + pos_paths = [(row, col + 1), (row, col - 1), (row + 1, col), (row - 1, col)] + for row_n, col_n in pos_paths: + if (row_n,col_n) not in seen: + if dfs(grid, word, curr_i + 1, row_n, col_n): + return True + + seen.remove((row,col)) + return False + + for row in range(len(grid)): + for col in range(len(grid[0])): + if grid[row][col] == word[0]: + if dfs(grid, word, 0, row, col): + return True + + return False \ No newline at end of file diff --git a/LeetCode/0080_Remove_Duplicates_from_Sorted_Array_II.py b/LeetCode/0080_Remove_Duplicates_from_Sorted_Array_II.py new file mode 100644 index 0000000..0d63cae --- /dev/null +++ b/LeetCode/0080_Remove_Duplicates_from_Sorted_Array_II.py @@ -0,0 +1,34 @@ +''' +https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/ +''' + + +class Solution: + # we want to leave at most two of each element + def removeDuplicates(self, nums: list) -> int: + length = 0 + lastNum = None + lastLastNum = None + + # iterate in reverse order so that when we modify the list + # it doesn't affect the order of the unvisited elements + i = len(nums) - 1 + while i >= 0: + el = nums[i] + if el == lastLastNum: + del nums[i] + else: + length += 1 + lastLastNum = lastNum + lastNum = el + i -= 1 + + return length + + +if __name__ == '__main__': + solution = Solution() + input = [1, 1, 1, 2, 2, 3] + solution.removeDuplicates(input) + print(input) + print(len(input)) diff --git a/LeetCode/0082_Remove_Duplicates_from_Sorted_List_II.py b/LeetCode/0082_Remove_Duplicates_from_Sorted_List_II.py new file mode 100644 index 0000000..0590137 --- /dev/null +++ b/LeetCode/0082_Remove_Duplicates_from_Sorted_List_II.py @@ -0,0 +1,19 @@ +# Definition for singly-linked list. +#class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def deleteDuplicates(self, head: ListNode) -> ListNode: + if head is None: + return head + + while (head.next is not None) and (head.val == head.next.val): + while (head.next is not None) and (head.val == head.next.val): + head = head.next + head = head.next + if head is None: + return head + + head.next = self.deleteDuplicates(head.next) + return head \ No newline at end of file diff --git a/LeetCode/0084_Largest_Rectangle_in_Histogram.py b/LeetCode/0084_Largest_Rectangle_in_Histogram.py new file mode 100644 index 0000000..8e1b7e0 --- /dev/null +++ b/LeetCode/0084_Largest_Rectangle_in_Histogram.py @@ -0,0 +1,15 @@ +class Solution: + def largestRectangleArea(self, heights: List[int]) -> int: + heights.append(0) + lst = [-1] + output = 0 + + for i in range(len(heights)): + while (heights[i] < heights[lst[-1]]): + height = heights[lst.pop()] + width = i - lst[-1] - 1 + output = max(output, height * width) + lst.append(i) + + heights.pop() + return output diff --git a/LeetCode/0086_Partition_List.py b/LeetCode/0086_Partition_List.py new file mode 100644 index 0000000..6248e3e --- /dev/null +++ b/LeetCode/0086_Partition_List.py @@ -0,0 +1,36 @@ +class Solution(object): + def partition(self, head, x): + """ + :type head: ListNode + :type x: int + :rtype: ListNode + """ + + # before and after are the two pointers used to create two list + # before_head and after_head are used to save the heads of the two lists. + # All of these are initialized with the dummy nodes created. + before = before_head = ListNode(0) + after = after_head = ListNode(0) + + while head: + # If the original list node is lesser than the given x, + # assign it to the before list. + if head.val < x: + before.next = head + before = before.next + else: + # If the original list node is greater or equal to the given x, + # assign it to the after list. + after.next = head + after = after.next + + # move ahead in the original list + head = head.next + + # Last node of "after" list would also be ending node of the reformed list + after.next = None + # Once all the nodes are correctly assigned to the two lists, + # combine them to form a single list which would be returned. + before.next = after_head.next + + return before_head.next diff --git a/LeetCode/0088_Merge_Sorted_Array.py b/LeetCode/0088_Merge_Sorted_Array.py new file mode 100644 index 0000000..902755b --- /dev/null +++ b/LeetCode/0088_Merge_Sorted_Array.py @@ -0,0 +1,8 @@ +class Solution: + def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: + for x in nums2: + for y in range(len(nums1)): + if nums1[y]==0: + nums1[y]+=x + break + nums1.sort() diff --git a/LeetCode/0091_Decode_Ways.py b/LeetCode/0091_Decode_Ways.py new file mode 100644 index 0000000..e5d83ff --- /dev/null +++ b/LeetCode/0091_Decode_Ways.py @@ -0,0 +1,20 @@ +class Solution: + def numDecodings(self, s: str) -> int: + def in_range(n): + if n[0] == '0': + return False + to_int = int(n) + if to_int <= 26 and to_int > 0: + return True + return False + + N = len(s) + a, b = 1, 1 + if N == 0 or s[0] == '0': + return 0 + + for i in range(1, N): + extra = a if in_range(s[i-1:i+1]) else 0 + c = extra + (b if in_range(s[i]) else 0) + a, b = b, c + return b diff --git a/LeetCode/0093_Restore_IP_address.py b/LeetCode/0093_Restore_IP_address.py new file mode 100644 index 0000000..0f2630e --- /dev/null +++ b/LeetCode/0093_Restore_IP_address.py @@ -0,0 +1,53 @@ +class Solution: + + def restoreIpAddresses(self, s: str) -> list: + + return self.convert(s) + + def convert(self,s): + + sz = len(s) + + # Check for string size + if sz > 12: + return [] + snew = s + l = [] + + # Generating different combinations. + for i in range(1, sz - 2): + for j in range(i + 1, sz - 1): + for k in range(j + 1, sz): + snew = snew[:k] + "." + snew[k:] + snew = snew[:j] + "." + snew[j:] + snew = snew[:i] + "." + snew[i:] + + # Check for the validity of combination + if self.is_valid(snew): + l.append(snew) + + snew = s + + return l + + + + + def is_valid(self,ip): + + # Splitting by "." + ip = ip.split(".") + + # Checking for the corner cases + for i in ip: + if (len(i) > 3 or int(i) < 0 or + int(i) > 255): + return False + if len(i) > 1 and int(i) == 0: + return False + if (len(i) > 1 and int(i) != 0 and + i[0] == '0'): + return False + + return True + \ No newline at end of file diff --git a/LeetCode/0094_Binary_Tree_Inorder_Traversal.py b/LeetCode/0094_Binary_Tree_Inorder_Traversal.py new file mode 100644 index 0000000..d1b9e92 --- /dev/null +++ b/LeetCode/0094_Binary_Tree_Inorder_Traversal.py @@ -0,0 +1,19 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def inorderTraversal(self, root: TreeNode) -> List[int]: + res = [] + myStack = [] + curr = root + while len(myStack) or curr is not None: + while curr is not None: + myStack.append(curr) + curr = curr.left + curr = myStack.pop() + res.append(curr.val) + curr = curr.right + return res diff --git a/LeetCode/0098_Validate_Binary_Search_Tree.py b/LeetCode/0098_Validate_Binary_Search_Tree.py new file mode 100644 index 0000000..35253cc --- /dev/null +++ b/LeetCode/0098_Validate_Binary_Search_Tree.py @@ -0,0 +1,16 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right + +class Solution: + def isValidBST(self, root: TreeNode, sm=[], gt=[]) -> bool: + if root is None: + return True + + if any([root.val <= x for x in sm]) or any([root.val >= x for x in gt]): + return False + + return (root.left is None or self.isValidBST(root.left, sm, gt + [root.val])) and (root.right is None or self.isValidBST(root.right, sm + [root.val], gt)) diff --git a/LeetCode/0100_Same_Tree.py b/LeetCode/0100_Same_Tree.py new file mode 100644 index 0000000..68c723f --- /dev/null +++ b/LeetCode/0100_Same_Tree.py @@ -0,0 +1,20 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution(object): + def isSameTree(self, p, q): + if(p is None and q is None): + return True + + if(p==None or q==None): + return False + + if(p.val!=q.val): + return False + + else: + return self.isSameTree( p.right, q.right) and self.isSameTree( p.left, q.left) + \ No newline at end of file diff --git a/LeetCode/0101_Symmetric_Tree.py b/LeetCode/0101_Symmetric_Tree.py new file mode 100644 index 0000000..6ee51ea --- /dev/null +++ b/LeetCode/0101_Symmetric_Tree.py @@ -0,0 +1,19 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def isSymmetric(self, root: TreeNode) -> bool: + if root == None: + return True + + return self.isMirror(root.left, root.right) + + + def isMirror(self, a: TreeNode, b: TreeNode) -> bool: + if (a and b) and (a.val == b.val): + return self.isMirror(a.left, b.right) and self.isMirror(a.right, b.left) + + return a == None and b == None diff --git a/LeetCode/0102_Binary_Tree_Level_Order_Traversal.py b/LeetCode/0102_Binary_Tree_Level_Order_Traversal.py new file mode 100644 index 0000000..05fe397 --- /dev/null +++ b/LeetCode/0102_Binary_Tree_Level_Order_Traversal.py @@ -0,0 +1,56 @@ +""" +Level Order Traversal - BFS + +A Tree Algorithm where the nodes in a tree are visited in a level by level fashion. +i.e Nodes at each level are processed before moving on to the next. + +Steps + 1. For every node, add to a queue. + 2. Process the node and pop from the front of the queue. + 3. Add its left and right child to the queue. + +Time complexity is O(N) since we visit every node at least once. N is the number of nodes in the tree. +Space complexity is O(N) since we make use of a queue data structure having a maximum of size N. + + +Sample Binary Tree: + + 8 + / \ + 3 10 + / \ \ + 1 6 14 + +Level-Order Traversal of this binary tree results in: +output = [[8], [3,10], [1,6,14]] +""" + +# Code implementation +def levelOrder(self, root: TreeNode) -> List[List[int]]: + import collections + output = [] + queue = collections.deque([root]) + + if root == None: + return [] + + while queue: + num_of_nodes = len(queue) + curr_level = [] + + for node in range(num_of_nodes): + curr_node = queue.popleft() + curr_level.append(curr_node.val) + + if curr_node.left: + queue.append(curr_node.left) + + if curr_node.right: + queue.append(curr_node.right) + + output.append(curr_level) + + + + return output + \ No newline at end of file diff --git a/LeetCode/0103_Binary_Tree_Zigzag_Level_Order_Traversal.py b/LeetCode/0103_Binary_Tree_Zigzag_Level_Order_Traversal.py new file mode 100644 index 0000000..09d4ed5 --- /dev/null +++ b/LeetCode/0103_Binary_Tree_Zigzag_Level_Order_Traversal.py @@ -0,0 +1,31 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]: + q = [] + t = [] + + if root: + q.append((0, root)) + + while len(q) > 0: + level, curr = q.pop(0) + + if level >= len(t): + t.append([]) + t[level].append(curr.val) + + if curr.left: + q.append((level + 1, curr.left)) + if curr.right: + q.append((level + 1, curr.right)) + + for i in range(len(t)): + if i % 2 == 1: + t[i] = reversed(t[i]) + return t + diff --git a/LeetCode/0104_Maximum_Depth_of_Binary_Tree.py b/LeetCode/0104_Maximum_Depth_of_Binary_Tree.py new file mode 100644 index 0000000..0d0a184 --- /dev/null +++ b/LeetCode/0104_Maximum_Depth_of_Binary_Tree.py @@ -0,0 +1,12 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def maxDepth(self, root: TreeNode) -> int: + if root==None: + return 0 + else: + return max(self.maxDepth(root.left),self.maxDepth(root.right))+1 diff --git a/LeetCode/0105_Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal.py b/LeetCode/0105_Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal.py new file mode 100644 index 0000000..51ef9c0 --- /dev/null +++ b/LeetCode/0105_Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal.py @@ -0,0 +1,19 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: + if len(preorder) == 0: + return None + + n = preorder.pop(0) + i = inorder.index(n) + + l = self.buildTree(preorder[:i], inorder[:i]) + r = self.buildTree(preorder[i:], inorder[i+1:]) + + return TreeNode(n, l, r) + diff --git a/LeetCode/0106_Construct_Binary_Tree_from_Inorder_and_Postorder_Traversal.py b/LeetCode/0106_Construct_Binary_Tree_from_Inorder_and_Postorder_Traversal.py new file mode 100644 index 0000000..4157914 --- /dev/null +++ b/LeetCode/0106_Construct_Binary_Tree_from_Inorder_and_Postorder_Traversal.py @@ -0,0 +1,22 @@ +class Solution: + def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode: + return self.helperFunc(inorder, postorder, 0, len(inorder)-1, len(postorder)-1) + def helperFunc(self, inorder: List[int], postorder: List[int], left: int, right: int, postIndex: int) -> TreeNode: + # checks if there is node required else puts null in the binary tree + if postIndex == -1: + return + # creating the root of the subtree from the value present at current postIndex + root = TreeNode(postorder[postIndex]) + # we find the root's value in order to divide them into left and right subtree + x = 0 + for i in range(len(inorder)): + if root.val == inorder[i]: + x = i + # finding corresponding values that are roots for left and right subtrees or assign -1 + right_post = -1 if abs(right - x) == 0 else postIndex - 1 + left_post = -1 if abs(left - x) == 0 else postIndex -1 - abs(right - x) + # calling recursively helperFunc for left and right subtrees + root.left = self.helperFunc(inorder, postorder, left, x-1, left_post) + root.right = self.helperFunc(inorder, postorder, x+1, right, right_post) + return root + \ No newline at end of file diff --git a/LeetCode/0107_Binary_Tree_Level_Order_Traversal_II.py b/LeetCode/0107_Binary_Tree_Level_Order_Traversal_II.py new file mode 100644 index 0000000..0d2e142 --- /dev/null +++ b/LeetCode/0107_Binary_Tree_Level_Order_Traversal_II.py @@ -0,0 +1,27 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def levelOrderBottom(self, root: TreeNode) -> List[List[int]]: + q = [] + t = [] + + if root: + q.append((0, root)) + + while len(q) > 0: + level, curr = q.pop(0) + + if level >= len(t): + t.append([]) + t[level].append(curr.val) + + if curr.left: + q.append((level + 1, curr.left)) + if curr.right: + q.append((level + 1, curr.right)) + + return reversed(t) diff --git a/LeetCode/0110_balanced_binary_tree.py b/LeetCode/0110_balanced_binary_tree.py new file mode 100644 index 0000000..e99066c --- /dev/null +++ b/LeetCode/0110_balanced_binary_tree.py @@ -0,0 +1,21 @@ +#class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + + +class Solution(object): + # @param root, a tree node + # @return a boolean + def isBalanced(self, root): + def getHeight(root): + if root is None: + return 0 + left_height, right_height = \ + getHeight(root.left), getHeight(root.right) + if left_height < 0 or right_height < 0 or \ + abs(left_height - right_height) > 1: + return -1 + return max(left_height, right_height) + 1 + return (getHeight(root) >= 0) \ No newline at end of file diff --git a/LeetCode/0112_Path_Sum.py b/LeetCode/0112_Path_Sum.py new file mode 100644 index 0000000..b2faa86 --- /dev/null +++ b/LeetCode/0112_Path_Sum.py @@ -0,0 +1,14 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right + +class Solution: + def hasPathSum(self, root: TreeNode, sum: int) -> bool: + if not root: + return False + if not root.left and not root.right: + return root.val == sum + return self.hasPathSum(root.left,sum-root.val) or self.hasPathSum(root.right,sum-root.val) \ No newline at end of file diff --git a/LeetCode/0118_pascal_triangle.py b/LeetCode/0118_pascal_triangle.py new file mode 100644 index 0000000..ccd4440 --- /dev/null +++ b/LeetCode/0118_pascal_triangle.py @@ -0,0 +1,9 @@ +class Solution: + def generate(self, numRows: int) -> List[List[int]]: + if numRows==0: + return [] + triangle=[[1]] + for row in range(numRows-1): + triangle.append([1]+[triangle[-1][i]+triangle[-1][i+1] for i in range(row)]+[1]) + return triangle + \ No newline at end of file diff --git a/LeetCode/0119_Pascal_Triangle2.py b/LeetCode/0119_Pascal_Triangle2.py new file mode 100644 index 0000000..02171f9 --- /dev/null +++ b/LeetCode/0119_Pascal_Triangle2.py @@ -0,0 +1,20 @@ +class Solution(object): + def getRow(self, rowIndex): + """ + :type rowIndex: int + :rtype: List[int] + """ + + if rowIndex == 0: + return [1] + if rowIndex == 1: + return [1,1] + + init = [1,1] + for i in range(0, rowIndex-1): + new_vec = [] + for v in range(0, len(init)-1): + new_vec.append(init[v] + init[v+1]) + new_vec = [1] + new_vec + [1] + init = new_vec + return init diff --git a/LeetCode/0121_Best_Time_to_Buy_and_Sell_Stock.py b/LeetCode/0121_Best_Time_to_Buy_and_Sell_Stock.py new file mode 100644 index 0000000..bd751d4 --- /dev/null +++ b/LeetCode/0121_Best_Time_to_Buy_and_Sell_Stock.py @@ -0,0 +1,11 @@ +class Solution: + def maxProfit(self, prices: List[int]) -> int: + if len(prices) == 0: + return 0 + profit = 0 + mincost = prices[0] + + for i in range(1, len(prices)): + profit = max(profit, prices[i] - mincost) + mincost = min(mincost, prices[i]) + return profit \ No newline at end of file diff --git a/LeetCode/0123_Best_Time_To_Buy_And_Sell_Stock_III.py b/LeetCode/0123_Best_Time_To_Buy_And_Sell_Stock_III.py new file mode 100644 index 0000000..96e2220 --- /dev/null +++ b/LeetCode/0123_Best_Time_To_Buy_And_Sell_Stock_III.py @@ -0,0 +1,49 @@ + +''' + Python program to solve issue: 0123- Best Time to Buy adn Sell Stock + + Issue Id: #383 +''' + + +class Solution: + + #Evalutes the all days to buy and sell stock & Generate maximum profit + def maxProfit(self, prices: List[int]) -> int: + + #Checks whether price array is empty or less then 2 elements + if prices==None or len(prices) < 2: + return 0 + + maxProfit=0 #Stores maximum profit + + minPrice=prices[0] #the minimum price from the first day to day k-1 + + #the maximum profit with at most one transaction from the first day to day k + first=[0 for x in range(0,len(prices))] + + #Evaluates maximum profit from first day to last day + for i in range(1,len(prices)): + maxProfit= max(maxProfit, prices[i]- minPrice) + first[i]= maxProfit + minPrice= min(minPrice, prices[i]) + + maxProfit=0 + maxPrice=prices[len(prices)-1] #the maximum price from day k+1 to the last day + + #the maximum profit with at most one transaction from day k to the last day + second=[0 for x in range(len(prices))] + + #Evaluates maximum profit from last day to first day + for j in range(len(prices)-2,-1,-1): + maxProfit = max(maxProfit, (maxPrice - prices[j])) + second[j] = int(maxProfit) + maxPrice = max(maxPrice, prices[j]) + + maxProfit=0 + + #Evaluates maximum profit for all days with at most TWO transaction + for k in range(0,len(prices)): + maxProfit= max(maxProfit, first[k]+second[k]) + + return maxProfit \ No newline at end of file diff --git a/LeetCode/0125_Valid_Palindrome.py b/LeetCode/0125_Valid_Palindrome.py new file mode 100644 index 0000000..acffcdd --- /dev/null +++ b/LeetCode/0125_Valid_Palindrome.py @@ -0,0 +1,18 @@ +class Solution: + def isPalindrome(self, s: str) -> bool: + alphnum = "" + #Extract only alphanumeric characters from the given string + for i in s: + #Check whether the character is a lowercase letter or a number + if ord(i)>=ord('a') and ord(i)<=ord('z') or ord(i)>=ord("0") and ord(i)<=ord("9"): + alphnum+=i + #Check whether the character is an uppercase letter. + #If yes,convert to lower case + elif ord(i)>=ord('A') and ord(i)<=ord('Z'): + i = chr(32+ord(i)) + alphnum+=i + #Reverse the alphanumeric string and check whether it is a palindrome + rev= alphnum[::-1] + result= rev==alphnum + return result + \ No newline at end of file diff --git a/LeetCode/0126_Word_Ladder_II.py b/LeetCode/0126_Word_Ladder_II.py new file mode 100644 index 0000000..c00115a --- /dev/null +++ b/LeetCode/0126_Word_Ladder_II.py @@ -0,0 +1,26 @@ +class Solution: + def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]: + + from collections import defaultdict + + wordList = set(wordList) + list1 = [] + layer = {} + layer[beginWord] = [[beginWord]] + + while layer: + newlayer = defaultdict(list) + for a in layer: + if a == endWord: + list1.extend(b for b in layer[a]) + else: + for i in range(len(a)): + for j in 'abcdefghijklmnopqrstuvwxyz': + new1 = a[:i]+j+a[i+1:] + if new1 in wordList: + newlayer[new1]+=[k+[new1] for k in layer[a]] + + wordList -= set(newlayer.keys()) + layer = newlayer + + return list1 \ No newline at end of file diff --git a/LeetCode/0134_Gas_Station.py b/LeetCode/0134_Gas_Station.py new file mode 100644 index 0000000..161388d --- /dev/null +++ b/LeetCode/0134_Gas_Station.py @@ -0,0 +1,41 @@ +""" +134. Gas Station Problem + +Problem:- +There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. +You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). +You begin the journey with an empty tank at one of the gas stations. +Return the starting gas station's index if you can travel around the circuit once in the clockwise direction, otherwise return -1. + +Input:- gas = [1,2,3,4,5], gas is the array consisting of the gas can get at i th stop + cost= [3,4,5,1,2], cost is the array consisting of the cost to travel from i to i+1 index + +Output:- 3, we have to return the index from where we can start journey and traverse all stops in clockwise manner + +Time complexity :- O(N) where N is the number is the size of array(stops) +Space complexity:- O(1) + +""" + +class Solution: + def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int: + # total_fuel variable is maintained to check if path is possible or not if sum(gas) < sum(cost) return -1 + n = len(gas) + curr_fuel = 0 + total_fuel = 0 + start_idx = 0 + + for i in range(n): + curr_fuel += gas[i]-cost[i] + total_fuel += gas[i]-cost[i] + # at any index if fuel becomes less than 0 then we have to choose new starting index + if curr_fuel < 0: + # start_idx will be i+1 because at i th index out curr_fuel became < 0 + # so we start from any index between start_idx and i there will be no valid start_idx + start_idx = i+1 + # reset the curr_fuel to 0 as we have chose new start_idx + curr_fuel = 0 + # at last check if start_idx is less than n and total_fuel is not less than 0 return start_idx else -1 + return start_idx if start_idx < n and total_fuel>=0 else -1 + + diff --git a/LeetCode/0137_Single_Number_II.py b/LeetCode/0137_Single_Number_II.py new file mode 100644 index 0000000..7792dcf --- /dev/null +++ b/LeetCode/0137_Single_Number_II.py @@ -0,0 +1,6 @@ +class Solution: + def singleNumber(self, nums: List[int]) -> int: + used=[] + for x in nums: + if nums.count(x)==1: + return x diff --git a/LeetCode/0138_Copy_List_with_Random_Pointer.py b/LeetCode/0138_Copy_List_with_Random_Pointer.py new file mode 100644 index 0000000..a2f9787 --- /dev/null +++ b/LeetCode/0138_Copy_List_with_Random_Pointer.py @@ -0,0 +1,31 @@ +""" +# Definition for a Node. +class Node: + def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): + self.val = int(x) + self.next = next + self.random = random +""" + +def solve(head): + d = {} + h = head + while(h): + copy = Node(h.val) + d[h] = copy + h = h.next + h = head + while(h): + copy = d[h] + if(h.next): + copy.next = d[h.next] + if(h.random): + copy.random = d[h.random] + h = h.next + if(head): + return d[head] + return None + +class Solution: + def copyRandomList(self, head: 'Node') -> 'Node': + return solve(head) diff --git a/LeetCode/0141_Linked_List_Cycle.py b/LeetCode/0141_Linked_List_Cycle.py new file mode 100644 index 0000000..c26485b --- /dev/null +++ b/LeetCode/0141_Linked_List_Cycle.py @@ -0,0 +1,39 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + ''' + Solution using Floyd's cycle-finding algorithm (tortoise and hare) + ''' + + def hasCycle(self, head: ListNode) -> bool: + if not head or not head.next: + return False + + fast = slow = head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + + # If there is a cycle, fast will inevitably be on the same node as + # slow. + if fast is slow: + return True + return False + + +class SolutionO1: + ''' + Solution to follow up. Disregards contents of each ListNode. + ''' + + def hasCycle(self, head: ListNode) -> bool: + while head: + if head.val is None: + return True + head.val = None + head = head.next + return False diff --git a/LeetCode/0144_Binary_Tree_Preorder_Traversal.py b/LeetCode/0144_Binary_Tree_Preorder_Traversal.py new file mode 100644 index 0000000..05b735d --- /dev/null +++ b/LeetCode/0144_Binary_Tree_Preorder_Traversal.py @@ -0,0 +1,16 @@ +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right +class Solution: + def preorderTraversal(self, root: TreeNode) -> List[int]: + self.ans=[] + def preorder(root): + if root is None: + return + self.ans.append(root.val) + preorder(root.left) + preorder(root.right) + preorder(root) + return self.ans \ No newline at end of file diff --git a/LeetCode/0145_binary_tree_postorder_traversal.py b/LeetCode/0145_binary_tree_postorder_traversal.py new file mode 100644 index 0000000..ef7c7fc --- /dev/null +++ b/LeetCode/0145_binary_tree_postorder_traversal.py @@ -0,0 +1,18 @@ +class Solution(object): + def postorderTraversal(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + result, stack = [], [(root, False)] + while stack: + root, is_visited = stack.pop() + if root is None: + continue + if is_visited: + result.append(root.val) + else: + stack.append((root, True)) + stack.append((root.right, False)) + stack.append((root.left, False)) + return result \ No newline at end of file diff --git a/LeetCode/0146_LRU_Cache.py b/LeetCode/0146_LRU_Cache.py new file mode 100644 index 0000000..7a3f01d --- /dev/null +++ b/LeetCode/0146_LRU_Cache.py @@ -0,0 +1,28 @@ +class LRUCache: + + def __init__(self, capacity: int): + self.capacity = capacity + self.cache = collections.OrderedDict() + + + def get(self, key: int) -> int: + if key not in self.cache: + return -1 + else: + val = self.cache[key] + del self.cache[key] + self.cache[key] = val + return val + + def put(self, key: int, value: int) -> None: + if key in self.cache: + del self.cache[key] + elif len(self.cache) == self.capacity: + self.cache.popitem(last=False) + self.cache[key] = value + + +# Your LRUCache object will be instantiated and called as such: +# obj = LRUCache(capacity) +# param_1 = obj.get(key) +# obj.put(key,value) diff --git a/LeetCode/0151_Reverse_Words_in_a_String.py b/LeetCode/0151_Reverse_Words_in_a_String.py new file mode 100644 index 0000000..6e624f4 --- /dev/null +++ b/LeetCode/0151_Reverse_Words_in_a_String.py @@ -0,0 +1,10 @@ +class Solution: + def reverseWords(self, s): + list_of_string = s.split(' ') + #appliying filter function to remove extraspaces from list + new_list = list(filter(lambda x : True if (x!="") else False, list_of_string)) + #taking reverse of output list + new_list.reverse() + #joining the elements if list + final_string = " ".join(str(k) for k in new_list) + return final_string diff --git a/LeetCode/0155_Min_stack.py b/LeetCode/0155_Min_stack.py new file mode 100644 index 0000000..cdc92b4 --- /dev/null +++ b/LeetCode/0155_Min_stack.py @@ -0,0 +1,33 @@ +class MinStack: + + def __init__(self): + """ + initialize your data structure here. + """ + self.stack = [] + + + def push(self, x: int) -> None: + self.stack.append(x) + + + def pop(self) -> None: + self.stack.pop() # = self.stack[:-1] #pop() + + + def top(self) -> int: + return self.stack[-1] + + + + def getMin(self) -> int: + return min(self.stack) + + + +# Your MinStack object will be instantiated and called as such: +# obj = MinStack() +# obj.push(x) +# obj.pop() +# param_3 = obj.top() +# param_4 = obj.getMin() diff --git a/LeetCode/0165_Compare_Version_Numbers.py b/LeetCode/0165_Compare_Version_Numbers.py new file mode 100644 index 0000000..33fc300 --- /dev/null +++ b/LeetCode/0165_Compare_Version_Numbers.py @@ -0,0 +1,14 @@ +class Solution: + def compareVersion(self, version1: str, version2: str) -> int: + v1 = version1.split(".") + v2 = version2.split(".") + while len(v1) < len(v2): + v1.append("0") + while len(v2) < len(v1): + v2.append("0") + for i in range(len(v1)): + a = int(v1[i]) + b = int(v2[i]) + if a != b: + return (a-b)//abs(a-b) + return 0 diff --git a/LeetCode/0167_Two_Sum_II.py b/LeetCode/0167_Two_Sum_II.py new file mode 100644 index 0000000..6d48eb1 --- /dev/null +++ b/LeetCode/0167_Two_Sum_II.py @@ -0,0 +1,15 @@ +# Problem name : Two Sum II - Input array is sorted +# Problem link : https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/ +# Contributor : Herumb Shandilya + +class Solution: + def twoSum(self, numbers: List[int], target: int) -> List[int]: + for x in numbers: + if x > target: + break + else: + if target - x == x: + return (numbers.index(x)+1,numbers.index(x)+2) + else: + if target - x in numbers: + return(numbers.index(x)+1,numbers.index(target - x)+1) \ No newline at end of file diff --git a/LeetCode/0169_Majority_Element.py b/LeetCode/0169_Majority_Element.py new file mode 100644 index 0000000..dec71e1 --- /dev/null +++ b/LeetCode/0169_Majority_Element.py @@ -0,0 +1,28 @@ +# this class will give us a solution +class Solution: + + # the function to find the majority element + def majorityElement(self, arr): + """ + finds the majority element in the arr + :param arr: List[int] a list with elements + :return: int , the majority element + """ + + # a dictionary of numbers we have seen + seen_numbers = {} + + if len(arr) <= 2: + return arr[0] + + # goes through the list of numbers and count the appearance amount + for num in arr: + # adds it to the dictionary + if num not in seen_numbers: + seen_numbers[num] = 1 + else: + if (seen_numbers[num] + 1) >= (len(arr) / 2): + return num + else: + # adds one to the counter + seen_numbers[num] += 1 diff --git a/LeetCode/0190_Reverse_bits.py b/LeetCode/0190_Reverse_bits.py new file mode 100644 index 0000000..cfd8a99 --- /dev/null +++ b/LeetCode/0190_Reverse_bits.py @@ -0,0 +1,5 @@ +class Solution: + def reverseBits(self, n: int) -> int: + + s='{0:032b}'.format(n)[::-1] + return int(s,2) \ No newline at end of file diff --git a/LeetCode/0191_Number_of_1_bits.py b/LeetCode/0191_Number_of_1_bits.py new file mode 100644 index 0000000..8454fa0 --- /dev/null +++ b/LeetCode/0191_Number_of_1_bits.py @@ -0,0 +1,4 @@ +class Solution: + def hammingWeight(self, n: int) -> int: + + return '{0:b}'.format(n).count('1') \ No newline at end of file diff --git a/LeetCode/0198_House_Robber.py b/LeetCode/0198_House_Robber.py new file mode 100644 index 0000000..097b5e6 --- /dev/null +++ b/LeetCode/0198_House_Robber.py @@ -0,0 +1,20 @@ +def rob(self, nums: List[int]) -> int: + length = len(nums) + if length == 0: + return 0 + dp = [0] * len(nums) + dp[0] = nums[0] + for i in range(1,length): + if i==1: + dp[i] = max(dp[0],nums[i]) + elif i==2: + dp[i] = dp[0]+nums[i] + else: + dp[i] = max(dp[i-2],dp[i-3]) + nums[i] + return max(dp[length-1],dp[length-2]) + +''' +n = len(nums) +Time complexity = O(n) +Space complexity = O(n) +''' \ No newline at end of file diff --git a/LeetCode/0200_Number_of_Islands.py b/LeetCode/0200_Number_of_Islands.py new file mode 100644 index 0000000..a297048 --- /dev/null +++ b/LeetCode/0200_Number_of_Islands.py @@ -0,0 +1,26 @@ +class Solution(object): + def numIslands(self, grid): + """ + :type grid: List[List[str]] + :rtype: int + """ + cnt = 0 + + for i in range(len(grid)): + for j in range(len(grid[i])): + if grid[i][j] == "1": + cnt += 1 + self.removeIsland(grid, i, j) + return cnt + + # recursive function for replacing adjacent "1"s + def removeIsland(self, grid, i, j): + if i < 0 or j < 0 or i >= len(grid) or j >= len(grid[0]): + return + if grid[i][j] == "0": + return + grid[i][j] = "0" + self.removeIsland(grid, i+1, j) + self.removeIsland(grid, i-1, j) + self.removeIsland(grid, i, j+1) + self.removeIsland(grid, i, j-1) diff --git a/LeetCode/0202_Happy_Number.py b/LeetCode/0202_Happy_Number.py new file mode 100644 index 0000000..119036a --- /dev/null +++ b/LeetCode/0202_Happy_Number.py @@ -0,0 +1,13 @@ +class Solution(object): + def isHappy(self, n): + """ + :type n: int + :rtype: bool + """ + checked = [] + while n != 1 and n not in checked: + checked.append(n) + n = sum([int(i) ** 2 for i in str(n)]) + if n == 1: + return True + return False \ No newline at end of file diff --git a/LeetCode/0203_Remove_Linked_List_Elements.py b/LeetCode/0203_Remove_Linked_List_Elements.py new file mode 100644 index 0000000..9f8febb --- /dev/null +++ b/LeetCode/0203_Remove_Linked_List_Elements.py @@ -0,0 +1,25 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next + +class Solution(object): + def removeElements(self, head, val): + """ + :type head: ListNode + :type val: int + :rtype: ListNode + """ + while head: + if head.val == val: + head = head.next + else: + break + currentNode = head + while currentNode: + while currentNode.next and currentNode.next.val == val: + currentNode.next = currentNode.next.next + + currentNode = currentNode.next + return head diff --git a/LeetCode/0208_Implement_Trie.py.py b/LeetCode/0208_Implement_Trie.py.py new file mode 100644 index 0000000..2393881 --- /dev/null +++ b/LeetCode/0208_Implement_Trie.py.py @@ -0,0 +1,58 @@ +class TrieNode: + def __init__(self, val): + self.val = val + self.isEnd = False + self.children = [None for i in range(26)] +class Trie: + def __init__(self): + """ + Initialize your data structure here. + """ + self.root = TrieNode('*') + + + def insert(self, word: str) -> None: + """ + Inserts a word into the trie. + """ + node = self.root + for c in word: + x = ord(c) - ord('a') + if node.children[x] is None: + node.children[x] = TrieNode(c) + node = node.children[x] + node.isEnd = True + + def search(self, word: str) -> bool: + """ + Returns if the word is in the trie. + """ + node = self.root + for c in word: + x = ord(c) - ord('a') + if node.children[x] is not None: + node = node.children[x] + else: + return False + return node.isEnd + + + def startsWith(self, prefix: str) -> bool: + """ + Returns if there is any word in the trie that starts with the given prefix. + """ + node = self.root + for c in prefix: + x = ord(c) - ord('a') + if node.children[x] is not None: + node = node.children[x] + else: + return False + return True + + +# Your Trie object will be instantiated and called as such: +# obj = Trie() +# obj.insert(word) +# param_2 = obj.search(word) +# param_3 = obj.startsWith(prefix) \ No newline at end of file diff --git a/LeetCode/0212_Word_search_II.py b/LeetCode/0212_Word_search_II.py new file mode 100644 index 0000000..3c5de35 --- /dev/null +++ b/LeetCode/0212_Word_search_II.py @@ -0,0 +1,55 @@ +class Solution: + def neighbours(self, i): + n = [] + if i >= self.cols: + n.append(i-self.cols) + if i + self.cols < self.rows * self.cols: + n.append(i+self.cols) + if i % self.cols > 0: + n.append(i-1) + if i % self.cols < self.cols - 1: + n.append(i+1) + return n + + def search(self, s): + if len(self.words) == 0: + return False + l = 0 + r = len(self.words) - 1 + while l <= r-1: + c = (l+r)//2 + if self.words[c] < s: + l = c+1 + else: + r = c + if len(self.words[l]) < len(s): + return False + return self.words[l][:len(s)] == s + + def DFS(self, v, s): + if not self.search(s): + return + if s in self.words and s not in self.found: + self.found.append(s) + ne = self.neighbours(v) + for n in ne: + if self.used[n]: + continue + self.used[n] = True + self.DFS(n, s + self.board[n]) + self.used[n] = False + + + def findWords(self, board, words): + self.found = [] + self.words = sorted(words) + self.rows = len(board) + self.cols = len(board[0]) + self.board = [board[i][j] for i in range(len(board)) for j in range(len(board[0]))] + self.used = [False] * self.cols * self.rows + for i in range(len(self.board)): + self.used[i] = True + self.DFS(i, self.board[i]) + self.used[i] = False + return self.found + diff --git a/LeetCode/0213_House_robber2.py b/LeetCode/0213_House_robber2.py new file mode 100644 index 0000000..c5a93f9 --- /dev/null +++ b/LeetCode/0213_House_robber2.py @@ -0,0 +1,55 @@ +""" +213. House Robber II +You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses were broken into on the same night. +Given a list of non-negative integers nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police. +Input: nums = [2,3,2] +Output: 3 +Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2), because they are adjacent houses. + +This problem is solved using Dynamic Programming +Time Complexity:- O(N) +Space Complexity: O(N) , we need to make 2 DP arrays so it takes O(2N) space + +""" +class Solution: + def rob(self, nums: List[int]) -> int: + n = len( nums ) + # base conditions + # if there is no element in array + if n==0: + return 0 + # if there is only one element in array return the element + if n==1: + return nums[0] + # if there are 2 elements then return the max value out of both as we can't choose adjacent values together + if n==2: + return max(nums[0],nums[1]) + + + def max_profit(dp): + """ + This function finds the max profit by robbing the adjacent houses using DP + Input:- DP array of size n-1 + Output:- Max profit from that DP array + """ + len_dp = len( dp ) + dp[1] = max( dp[0], dp[1] ) + for k in range( 2, len_dp ): + dp[k] = max( dp[k - 1], dp[k] + dp[k - 2] ) + + return dp[-1] + + """ + We exclude the last element in first case then find max profit + we exculde the first element in second case then find max profit + we can't take both first and last element as they are adjacent + as last house is connected to first house + """ + # find the profit excluding the last house + dp_excludingLastElement = nums[:n - 1] + profit1 = max_profit(dp_excludingLastElement) + # find the profit using the first house + dp_excludingFirstElement = nums[1:n] + profit2 = max_profit(dp_excludingFirstElement) + # return the max profit out of both the possibilites + return max( profit1, profit2 ) \ No newline at end of file diff --git a/LeetCode/0215_Kth_Largest_Element_In_An_Array.py b/LeetCode/0215_Kth_Largest_Element_In_An_Array.py new file mode 100644 index 0000000..f9994b4 --- /dev/null +++ b/LeetCode/0215_Kth_Largest_Element_In_An_Array.py @@ -0,0 +1,6 @@ +import heapq +class Solution: + def findKthLargest(self, nums: List[int], k: int) -> int: + heapq.heapify(nums) + res = heapq.nlargest(k,nums) + return res[len(res)-1] \ No newline at end of file diff --git a/LeetCode/0216_Combination_Sum_III.py b/LeetCode/0216_Combination_Sum_III.py new file mode 100644 index 0000000..f555b1b --- /dev/null +++ b/LeetCode/0216_Combination_Sum_III.py @@ -0,0 +1,13 @@ +class Solution(object): + def combinationSum3(self, k, n): + ret = [] + self.dfs(list(range(1, 10)), k, n, [], ret) + return ret + + def dfs(self, nums, k, n, path, ret): + if k < 0 or n < 0: + return + if k == 0 and n == 0: + ret.append(path) + for i in range(len(nums)): + self.dfs(nums[i+1:], k-1, n-nums[i], path+[nums[i]], ret) \ No newline at end of file diff --git a/LeetCode/0222_Count_Complete_Tree_Nodes.py b/LeetCode/0222_Count_Complete_Tree_Nodes.py new file mode 100644 index 0000000..eb633a0 --- /dev/null +++ b/LeetCode/0222_Count_Complete_Tree_Nodes.py @@ -0,0 +1,25 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def countNodes(self, root: TreeNode) -> int: + + if root == None: return 0 + right, left = root, root + h_l , h_r = 0, 0 + + while left != None: + h_l +=1 + left = left.left + + while right != None: + h_r +=1 + right = right.right + + + if (h_l == h_r) : return(1 << h_l) -1 + + return 1+ self.countNodes(root.left) + self.countNodes(root.right) diff --git a/LeetCode/0231_Power_Of_Two.py b/LeetCode/0231_Power_Of_Two.py new file mode 100644 index 0000000..e9304e4 --- /dev/null +++ b/LeetCode/0231_Power_Of_Two.py @@ -0,0 +1,3 @@ +class Solution: + def isPowerOfTwo(self, x: int) -> bool: + return (x != 0) and ((x & (x - 1)) == 0); \ No newline at end of file diff --git a/LeetCode/0234_Palindrome_Linked_List_.py b/LeetCode/0234_Palindrome_Linked_List_.py new file mode 100644 index 0000000..2522fc7 --- /dev/null +++ b/LeetCode/0234_Palindrome_Linked_List_.py @@ -0,0 +1,42 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + + def reverse(self, head): + p = head.next + while p and p.next: + tmp = p.next + p.next = p.next.next + tmp.next = head.next + head.next = tmp + + def isPalindrome(self, head): + """ + :type head: ListNode + :rtype: bool + """ + + #get middle pointer + p1 = ListNode(0) + p1.next = head + p2 = p1 + while p2 and p2.next: + p1 = p1.next + p2 = p2.next.next + + # reverse second half of list + self.reverse(p1) + + # check palindrome + p1 = p1.next + p2 = head + while p1: + if p1.val != p2.val: + return False + p1 = p1.next + p2 = p2.next + return True \ No newline at end of file diff --git a/LeetCode/0237_Delete_Node_in_a_Linked_List.py b/LeetCode/0237_Delete_Node_in_a_Linked_List.py new file mode 100644 index 0000000..f9bbb08 --- /dev/null +++ b/LeetCode/0237_Delete_Node_in_a_Linked_List.py @@ -0,0 +1,14 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def deleteNode(self, node): + """ + :type node: ListNode + :rtype: void Do not return anything, modify node in-place instead. + """ + node.val = node.next.val + node.next = node.next.next diff --git a/LeetCode/0242_Valid_anagrams.py b/LeetCode/0242_Valid_anagrams.py new file mode 100644 index 0000000..35a1d99 --- /dev/null +++ b/LeetCode/0242_Valid_anagrams.py @@ -0,0 +1,4 @@ +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + + return (sorted(s) == sorted(t)) \ No newline at end of file diff --git a/LeetCode/0257_Binary_Tree_Paths.py b/LeetCode/0257_Binary_Tree_Paths.py new file mode 100644 index 0000000..9dad911 --- /dev/null +++ b/LeetCode/0257_Binary_Tree_Paths.py @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def __init__(self): + self.listOfPaths = [] #this list will save all paths and return + + def binaryTreePaths(self, root: TreeNode, path="") -> List[str]: + if(root==None): + return [] #nothing to return (it's a empty node) ... + + path += " " + str(root.val)#actual node value becomes a 'element route' + + if(root.left==None and root.right==None): + self.listOfPaths.append(path[1:].replace(" ", "->"))#question output format + + else: + self.binaryTreePaths(root.left, path) #scan by route in left node + self.binaryTreePaths(root.right, path)#scan by route in right node + return self.listOfPaths #return all paths + diff --git a/LeetCode/0258_Add_Digits.py b/LeetCode/0258_Add_Digits.py new file mode 100644 index 0000000..8f0800c --- /dev/null +++ b/LeetCode/0258_Add_Digits.py @@ -0,0 +1,5 @@ +class Solution: + def addDigits(self, num: int) -> int: + if num < 10: return num + if num % 9 == 0: return 9 + return num % 9 diff --git a/LeetCode/0260_Single_Number_III.py b/LeetCode/0260_Single_Number_III.py new file mode 100644 index 0000000..065d8e6 --- /dev/null +++ b/LeetCode/0260_Single_Number_III.py @@ -0,0 +1,7 @@ +class Solution: + def singleNumber(self, N: List[int]) -> int: + L, d = len(N), set() + for n in N: + if n in d: d.remove(n) + else: d.add(n) + return d \ No newline at end of file diff --git a/LeetCode/0268_Missing_Number.py b/LeetCode/0268_Missing_Number.py new file mode 100644 index 0000000..843b6dd --- /dev/null +++ b/LeetCode/0268_Missing_Number.py @@ -0,0 +1,16 @@ +class Solution: + def computeXOR(self,n:int) -> int: + if n%4==0: + return n + elif n%4==1: + return 1 + elif n%4==2: + return n+1 + else: + return 0 + def missingNumber(self, nums: List[int]) -> int: + all_xor = self.computeXOR(len(nums)) + current_xor = 0 + for i in nums: + current_xor^=i + return(all_xor^current_xor) \ No newline at end of file diff --git a/LeetCode/0273_Integer_to_English_Words.py b/LeetCode/0273_Integer_to_English_Words.py new file mode 100644 index 0000000..12a4a71 --- /dev/null +++ b/LeetCode/0273_Integer_to_English_Words.py @@ -0,0 +1,68 @@ +class Solution(object): + def numberToWords(self, num: int) -> str: + def decode(triple_str): + final_list = [] + + numbers = { "1": "One", + "2": "Two", + "3": "Three", + "4": "Four", + "5": "Five", + "6": "Six", + "7": "Seven", + "8": "Eight", + "9": "Nine", + "10": "Ten", + "11": "Eleven", + "12": "Twelve", + "13": "Thirteen", + "14": "Fourteen", + "15": "Fifteen", + "16": "Sixteen", + "17": "Seventeen", + "18": "Eighteen", + "19": "Nineteen"} + + tens = { "2": "Twenty", + "3": "Thirty", + "4": "Forty", + "5": "Fifty", + "6": "Sixty", + "7": "Seventy", + "8": "Eighty", + "9": "Ninety"} + + if int(triple_str[0]) != 0: + final_list.append("{} Hundred".format(numbers[triple_str[0]])) + if int(triple_str[1]) == 1: + final_list.append("{}".format(numbers[triple_str[1:3]])) + else: + if int(triple_str[1]) != 0: + final_list.append("{}".format(tens[triple_str[1]])) + if int(triple_str[2]) != 0: + final_list.append("{}".format(numbers[triple_str[2]])) + + return final_list + + + num_str = "{:0>12}".format(str(num)) + num_list = [] + final_num = "" + digit_dict = { 0: "Billion", + 3: "Million", + 6: "Thousand"} + + for x in range(0, 12, 3): + the_triple = num_str[x:x+3] + if the_triple == "000": + continue + else: + num_list.extend(decode(the_triple)) + if x == 9: break + num_list.append(digit_dict[x]) + + final_num = " ".join(num_list) + if final_num == "": + final_num = "Zero" + + return final_num diff --git a/LeetCode/0274_H_Index.py b/LeetCode/0274_H_Index.py new file mode 100644 index 0000000..086042b --- /dev/null +++ b/LeetCode/0274_H_Index.py @@ -0,0 +1,11 @@ +class Solution: + def hIndex(self, citations: List[int]) -> int: + citations.sort() + n = len(citations) + if n==0: + return 0 + if set(citations) == {0}: + return 0 + for i in range(n): + if n-i<=citations[i]: + return n-i \ No newline at end of file diff --git a/LeetCode/0279-PerfectSquares.py b/LeetCode/0279-PerfectSquares.py new file mode 100644 index 0000000..b94fca3 --- /dev/null +++ b/LeetCode/0279-PerfectSquares.py @@ -0,0 +1,15 @@ +class Solution(object): + def numSquares(self, n): + queue = collections.deque([(0, 0)]) + visited = set() + while queue: + val, dis = queue.popleft() + if val == n: + return dis + for i in range(1, n+1): + j = val + i*i + if j > n: + break + if j not in visited: + visited.add(j) + queue.append((j, dis+1)) \ No newline at end of file diff --git a/LeetCode/0283_Move_Zeroes.py b/LeetCode/0283_Move_Zeroes.py new file mode 100644 index 0000000..e445f63 --- /dev/null +++ b/LeetCode/0283_Move_Zeroes.py @@ -0,0 +1,12 @@ +class Solution: + def moveZeroes(self, nums: List[int]) -> None: + """ + Do not return anything, modify nums in-place instead. + """ + pos = 0 + for i in range(len(nums)): + if nums[i]!= 0: + if pos!=i: + nums[pos], nums[i] = nums[i], nums[pos] + pos += 1 + diff --git a/LeetCode/0289_Game_of_Life.py b/LeetCode/0289_Game_of_Life.py new file mode 100644 index 0000000..a312714 --- /dev/null +++ b/LeetCode/0289_Game_of_Life.py @@ -0,0 +1,42 @@ +class Solution: + def gameOfLife(self, board): + self.m = len(board) + self.n = len(board[0]) + self.board = [rows.copy() for rows in board] + for i in range(self.m): + for j in range(self.n): + state = self.board[i][j] + dataDict = self.CheckNeighbors(i,j) + nextGen = self.NextGenState(state,dataDict) + board[i][j] = nextGen + + + def CheckNeighbors(self,row,column): + retDict = {"live":0,"dead":0} + lb = max(column-1,0) + rb = min(column+2,self.n) + tb = max(row -1,0) + bb = min(row+2,self.m) + for rows in range(tb,bb): + for columns in range(lb,rb): + if rows != row or columns != column : + neighbor = self.board[rows][columns] + if neighbor == 1: + retDict["live"] += 1 + else: + retDict["dead"] += 1 + return retDict + + def NextGenState(self,state,dataDict): + finalState = 0 + liveNeighbors = dataDict["live"] + if state == 1: + if liveNeighbors == 2 or liveNeighbors == 3: + finalState = 1 + else: + if liveNeighbors == 3: + finalState = 1 + return finalState + + + diff --git a/LeetCode/0299_Bulls_and_Cows.py b/LeetCode/0299_Bulls_and_Cows.py new file mode 100644 index 0000000..f1253ad --- /dev/null +++ b/LeetCode/0299_Bulls_and_Cows.py @@ -0,0 +1,18 @@ +from collections import Counter +class Solution: + def getHint(self, secret: str, guess: str) -> str: + n = len(secret) + matched = [] + bulls = cows = 0 + for i in range(n): + if secret[i] == guess[i]: + bulls += 1 + + a = Counter(secret) + b = Counter(guess) + + for i in set(secret): + cows += min(a[i], b[i]) + + ans = str(bulls) + "A" + str(cows - bulls) + "B" + return ans \ No newline at end of file diff --git a/LeetCode/0326_Power_Of_Three.py b/LeetCode/0326_Power_Of_Three.py new file mode 100644 index 0000000..d39687d --- /dev/null +++ b/LeetCode/0326_Power_Of_Three.py @@ -0,0 +1,42 @@ +""" +Given an integer, write a function to determine if it is a power of three. + +Example 1: + +Input: 27 +Output: true +Example 2: + +Input: 0 +Output: false +Example 3: + +Input: 9 +Output: true +Example 4: + +Input: 45 +Output: false +Follow up: +Could you do it without using any loop / recursion? +""" +class Solution(object): + def isPowerOfThree(self, n): + if n<1: + return False + elif n == 1: + return True + elif n == 2: + return False + else: + while n > 2: + a, b = divmod(n, 3) + if b == 0: + n = a + else: + break + if n==1: + return True + else: + return False + diff --git a/LeetCode/0337_House_Robber_III.py b/LeetCode/0337_House_Robber_III.py new file mode 100644 index 0000000..1198458 --- /dev/null +++ b/LeetCode/0337_House_Robber_III.py @@ -0,0 +1,75 @@ +''' +337. House Robber III +The thief has found himself a new place for his thievery again. +There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. +After a tour, the smart thief realized that "all houses in this place forms a binary tree". +It will automatically contact the police if two directly-linked houses were broken into on the same night. +Determine the maximum amount of money the thief can rob tonight without alerting the police. +Example 1: + Input: [3,2,3,null,3,null,1] + 3 + / \ + 2 3 + \ \ + 3 1 + +Output: 7 + Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7. + +Time Complexity:- O(N) +Space Complexity:- O(N), as we are using dictionary to memoize the solution +''' + +def rob(self, root: TreeNode) -> int: + # this dp dictionary will help us reduce the time complexity by memoizing the solutions + dp = {} + + # this function will return the max profit that we can get + def rob_helper(root): + # base cases + if(root is None): + return 0 + # if we have the value for root in dp that we means we have calculated the value + # previously so we can simply return the saved value + if(root in dp.keys()): + return dp[root] + ''' + In this problem our constraints are:- + 1. If we add/rob the profit of parent then we can't add/rob profit of children + as the police will be alerted + 2. If we don't rob the parent then we can rob its child nodes + + Example:- + + lvl 1 3 + / \ + lvl 2 2 3 + \ \ + lvl 3 3 1 + In this if we add the profit for 3 then we can't add 2 and 3 from level 2 but add 3 and 1 from level 3 + If we add 2 and 3 from level 2 then we can't add profit from level 1 and 3 + Therefore, in a nutshell WE CAN'T ADD THE PROFIT OF 2 ADJACENT LEVEL/HOUSES + + ''' + + # It is the total profit if we exclude the parent and add the left and right child + profit1 = rob_helper(root.left) + rob_helper(root.right) + + # In this case we left child nodes and added the profit for parent node + profit2 = root.val + # As we robbed the parent node so we can't rob children + # but we can rob children of left and right child of parent + + # If root.left has left and right children then add there profit + if(root.left is not None): + profit2 += rob_helper(root.left.left) + rob_helper(root.left.right) + # If root.right has left and right children then add there profit + if(root.right is not None): + profit2 += rob_helper(root.right.left) + rob_helper(root.right.right) + + # save the max value in DP to memoize the solution + dp[root] = max(profit1, profit2) + + return dp[root] + + return rob_helper(root) diff --git a/LeetCode/0338_Counting_Bits.py b/LeetCode/0338_Counting_Bits.py new file mode 100644 index 0000000..57d8397 --- /dev/null +++ b/LeetCode/0338_Counting_Bits.py @@ -0,0 +1,12 @@ +def solve(n): + dp = [0]*(n+1) + offset = 1 + for i in range(1,n+1): + if(not i&(i-1)): + offset = i + dp[i] = dp[i-offset] + 1 + return dp + +class Solution: + def countBits(self, num: int) -> List[int]: + return solve(num) diff --git a/LeetCode/0342_Power_Of_Four.py b/LeetCode/0342_Power_Of_Four.py new file mode 100644 index 0000000..a3711ec --- /dev/null +++ b/LeetCode/0342_Power_Of_Four.py @@ -0,0 +1,9 @@ +import math +class Solution: + #Solution without loops/recursion + def isPowerOfFour(self, num: int) -> bool: + if(num!=0): #number 0 there isn't in the logarithmic function domain! + exponent = math.log(abs(num), 4) #I will discover the number which multiply 4 nth times. The result must be equal to num. Ex: 4^2 = 16 + #However, the exponent must to be an integer value for num to be a power of 4. For example, there are no 4's half number power! + return int(math.pow(4, int(exponent)))==num + return False #number zero was the input \ No newline at end of file diff --git a/LeetCode/0343_Integer_Break.py b/LeetCode/0343_Integer_Break.py new file mode 100644 index 0000000..6835228 --- /dev/null +++ b/LeetCode/0343_Integer_Break.py @@ -0,0 +1,17 @@ +class Solution: + def integerBreak(self, n: int) -> int: + if n < 3: + return 1 + if n == 3: + return 2 + mylist = [1, 2, 3] + for i in range(4, n+1): + temp = [i] + for j in range((i+1)//2): + temp.append(mylist[j]*mylist[-j-1]) + mylist.append(max(temp)) + print(mylist, temp) + return max(mylist) + +solution = Solution() +print(solution.integerBreak(n =4)) \ No newline at end of file diff --git a/LeetCode/0347_Top_K_Frequent_Elements.py b/LeetCode/0347_Top_K_Frequent_Elements.py new file mode 100644 index 0000000..9a828d1 --- /dev/null +++ b/LeetCode/0347_Top_K_Frequent_Elements.py @@ -0,0 +1,57 @@ +from collections import Counter +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + count = Counter(nums) + unique = list(count.keys()) + + def partition(left, right, pivot_index) -> int: + pivot_frequency = count[unique[pivot_index]] + # 1. move pivot to end + unique[pivot_index], unique[right] = unique[right], unique[pivot_index] + + # 2. move all less frequent elements to the left + store_index = left + for i in range(left, right): + if count[unique[i]] < pivot_frequency: + unique[store_index], unique[i] = unique[i], unique[store_index] + store_index += 1 + + # 3. move pivot to its final place + unique[right], unique[store_index] = unique[store_index], unique[right] + + return store_index + + def quickselect(left, right, k_smallest) -> None: + """ + Sort a list within left..right till kth less frequent element + takes its place. + """ + # base case: the list contains only one element + if left == right: + return + + # select a random pivot_index + pivot_index = random.randint(left, right) + + # find the pivot position in a sorted list + pivot_index = partition(left, right, pivot_index) + + # if the pivot is in its final sorted position + if k_smallest == pivot_index: + return + # go left + elif k_smallest < pivot_index: + quickselect(left, pivot_index - 1, k_smallest) + # go right + else: + quickselect(pivot_index + 1, right, k_smallest) + + n = len(unique) + # kth top frequent element is (n - k)th less frequent. + # Do a partial sort: from less frequent to the most frequent, till + # (n - k)th less frequent element takes its place (n - k) in a sorted array. + # All element on the left are less frequent. + # All the elements on the right are more frequent. + quickselect(0, n - 1, n - k) + # Return top k frequent elements + return unique[n - k:] diff --git a/LeetCode/0367_ValidPerfectSquare.py b/LeetCode/0367_ValidPerfectSquare.py new file mode 100644 index 0000000..d6c025b --- /dev/null +++ b/LeetCode/0367_ValidPerfectSquare.py @@ -0,0 +1,15 @@ +class Solution(object): + def isPerfectSquare(self, num): + """ + :type num: int + :rtype: bool + """ + + i = 1 + sum_odds = 0 + while sum_odds < num: + sum_odds += i + if sum_odds == num: + return True + i += 2 + return False \ No newline at end of file diff --git a/LeetCode/0368_Largest_Divisible_Subset.py b/LeetCode/0368_Largest_Divisible_Subset.py new file mode 100644 index 0000000..ea55aeb --- /dev/null +++ b/LeetCode/0368_Largest_Divisible_Subset.py @@ -0,0 +1,27 @@ +class Solution: + def largestDivisibleSubset(self, nums: List[int]) -> List[int]: + if len(nums) < 2: + return nums + #creating a monotonic sequence of list + nums.sort() + #creating a DP list to keep track of how many preceeding elements can divide ith element + dp = [1]*len(nums) + max_ind = 0 + #dp pass using the following condition + for i in range(1, len(nums)): + for j in range(i): + if nums[i]%nums[j] == 0: + dp[i] = max(dp[i], dp[j] + 1) + if dp[max_ind] < dp[i]: + max_ind = i + res = [] + res.append(nums[max_ind]) + prev = nums[max_ind] + #reconstructing the sequence by iterating backwards + for i in range(max_ind - 1, -1, -1): + if dp[i] > 0 and dp[max_ind]-1 == dp[i] and prev%nums[i] == 0: + res.append(nums[i]) + prev = nums[i] + max_ind = i + res.reverse() + return res \ No newline at end of file diff --git a/LeetCode/0371_sum_of_two_integers.py b/LeetCode/0371_sum_of_two_integers.py new file mode 100644 index 0000000..5f01711 --- /dev/null +++ b/LeetCode/0371_sum_of_two_integers.py @@ -0,0 +1,13 @@ +class Solution: + def getSum(self, a: int, b: int) -> int: + # 32 bits integer max and min + MAX = 0x7FFFFFFF + MIN = 0x80000000 + + mask = 0xFFFFFFFF + + while b != 0: + carry = a & b + a, b = (a ^ b) & mask, (carry << 1) & mask + + return a if a <= MAX else ~(a ^ mask) \ No newline at end of file diff --git a/LeetCode/0383_RansomNote.py b/LeetCode/0383_RansomNote.py new file mode 100644 index 0000000..4eb197b --- /dev/null +++ b/LeetCode/0383_RansomNote.py @@ -0,0 +1,6 @@ +class Solution: + def canConstruct(self, ransomNote: str, magazine: str) -> bool: + return all( + ransomNote.count(letter) <= magazine.count(letter) + for letter in set(ransomNote) + ) diff --git a/LeetCode/0389_FindTheDifference.py b/LeetCode/0389_FindTheDifference.py new file mode 100644 index 0000000..0da6419 --- /dev/null +++ b/LeetCode/0389_FindTheDifference.py @@ -0,0 +1,12 @@ +class Solution: + def findTheDifference(self, s: str, t: str) -> str: + a = 0 + b = 0 + if 0 <= len(s) <= 1000: + for chars in s: + if 97 <= ord(chars) <= 122: + a += ord(chars) + for letters in t: + if 97 <= ord(letters) <= 122: + b += ord(letters) + return chr(b - a) diff --git a/LeetCode/0401_Binary_Watch_.py b/LeetCode/0401_Binary_Watch_.py new file mode 100644 index 0000000..2b9f099 --- /dev/null +++ b/LeetCode/0401_Binary_Watch_.py @@ -0,0 +1,69 @@ +class Solution(object): + def combination(self, n, k, inp, res): + # inp is expected to be a list of size n + #print n,k,inp,res + if k == 0: + res.append([i for i in inp]) + return + if k > n: + return + #for i in range(1,n+1): + inp[n-1] = 1 + self.combination(n-1,k-1, inp, res) + inp[n-1] = 0 + self.combination(n-1, k, inp, res) + + + def getHours(self, h): + if h == 0: + return ["0"] + if h == 1: + return ["1", "2", "4", "8"] + if h == 2: + return ["3", "5", "6", "9", "10"] + if h == 3: + return ["7", "11"] + + def getMinutes(self, m): + inp = [0,0,0,0,0,0] + res = [] + self.combination(6, m, inp, res) + mins = [1, 2, 4, 8, 16, 32] + minutes = [] + for comb in res: + i = 0 + mn = 0 + while i < 6: + if comb[i] == 1: + mn += mins[i] + i += 1 + if mn > 59: + continue + if mn < 10: + minutes.append("0" + str(mn)) + else: + minutes.append(str(mn)) + return minutes + + def readBinaryWatch(self, num): + """ + :type num: int + :rtype: List[str] + """ + i = 0 + res = [] + + while i <= num: + h = i + m = num - i + if h < 4 and m < 6: + lh = self.getHours(h) + #print lh + lm = self.getMinutes(m) + #print lm + for hr in lh: + for mn in lm: + res.append(hr + ":" + mn) + i += 1 + + return res diff --git a/LeetCode/0414_Third_Maximum_Number.py b/LeetCode/0414_Third_Maximum_Number.py new file mode 100644 index 0000000..fdf1d00 --- /dev/null +++ b/LeetCode/0414_Third_Maximum_Number.py @@ -0,0 +1,7 @@ +class Solution: + def thirdMax(self, nums: List[int]) -> int: + nums_set = sorted(set(nums), reverse=True) + if len(nums_set) >= 3: + return nums_set[2] + else: + return nums_set[0] diff --git a/LeetCode/0437_Path_Sum_III.py b/LeetCode/0437_Path_Sum_III.py new file mode 100644 index 0000000..f85e902 --- /dev/null +++ b/LeetCode/0437_Path_Sum_III.py @@ -0,0 +1,31 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + count = 0 + past_sums = {} + + def pathSum(self, root: TreeNode, sum: int) -> int: + if root is not None: + self.recurse(root, 0, sum) + return self.count + + def recurse(self, node, summed, target): + if node is None: + return False + else: + summed += node.val + if summed == target: + self.count += 1 + if summed - target in self.past_sums: + self.count += self.past_sums[summed - target] + if summed in self.past_sums: + self.past_sums[summed] += 1 + else: + self.past_sums[summed] = 1 + self.recurse(node.left, summed, target) + self.recurse(node.right, summed, target) + self.past_sums[summed] -= 1 diff --git a/LeetCode/0443_String_Compression.py b/LeetCode/0443_String_Compression.py new file mode 100644 index 0000000..609ce2a --- /dev/null +++ b/LeetCode/0443_String_Compression.py @@ -0,0 +1,16 @@ +class Solution: + def compress(self, chars: List[str]) -> int: + read = 0 + while read < len(chars) - 1: + count = 1 + read_next = read + 1 + while read < len(chars) - 1 and chars[read_next] == chars[read]: + del chars[read_next] + count += 1 + if count > 1: + for char in str(count): + chars.insert(read_next, char) + read_next += 1 + read = read_next + return len(chars) + diff --git a/LeetCode/0448-Find-All-Numbers-Disappeared-in-an-Array.py b/LeetCode/0448-Find-All-Numbers-Disappeared-in-an-Array.py new file mode 100644 index 0000000..ba1f630 --- /dev/null +++ b/LeetCode/0448-Find-All-Numbers-Disappeared-in-an-Array.py @@ -0,0 +1,12 @@ +class Solution: + def findDisappearedNumbers(self, nums: List[int]) -> List[int]: + List=[] + for i in range(len(nums)): + val= abs(nums[i])-1 + if(nums[val]>0): + nums[val]=-nums[val] + for i in range(len(nums)): + if(nums[i]>0): + List.append(i+1) + return List + diff --git a/LeetCode/0452_Minimum_Number_of_Arrows_to_Burst_Balloons.py b/LeetCode/0452_Minimum_Number_of_Arrows_to_Burst_Balloons.py new file mode 100644 index 0000000..bd55865 --- /dev/null +++ b/LeetCode/0452_Minimum_Number_of_Arrows_to_Burst_Balloons.py @@ -0,0 +1,18 @@ +class Solution: + def findMinArrowShots(self, points: List[List[int]]) -> int: + if points == []: + return 0 + points.sort(key = lambda x: x[0]) + start = points[0][0] + end = points[0][1] + ans = len(points) + for i in range(1, len(points)): + if start <= points[i][0] <= end: + ans -= 1 + if points[i][1] < end: + end = points[i][1] + else: + start = points[i][0] + end = points[i][1] + + return ans diff --git a/LeetCode/0456_Find_132_Pattern.py b/LeetCode/0456_Find_132_Pattern.py new file mode 100644 index 0000000..c176439 --- /dev/null +++ b/LeetCode/0456_Find_132_Pattern.py @@ -0,0 +1,47 @@ +class Solution(object): + def find132pattern(self, nums: List[int]): + if not nums or len(nums)< 2: + return False + + m=0 + ln=len(nums) + for i in range(len(nums)-1, -1, -1): + n=nums[i] + if i+1nums[i+1]: + break + else: + m+=1 + else: + return False + + ln-=m + assert(ln and m) + mi=ln + s3mx=nums[ln-1] + ln-=1 + + s2mx=nums[mi] + while mis2mx: + s2mx=mx2 + elif n>s3mx: + s2mx=s3mx + s3mx=n + while mimx2 and n n: + return res + return res + + while l < r - 1: + mid = (l + r) // 2 + if sum(mid) <= n: + l = mid + else: + r = mid + + if sum(l) == n: + return str(l) + + return str(n - 1) diff --git a/LeetCode/0500_Keyboard_Row.py b/LeetCode/0500_Keyboard_Row.py new file mode 100644 index 0000000..40fb9c8 --- /dev/null +++ b/LeetCode/0500_Keyboard_Row.py @@ -0,0 +1,6 @@ +class Solution: + + def findWords(self, words: List[str]) -> List[str]: + rows = ["qwertyuiop", "asdfghjkl", "zxcvbnm"] + is_in_row = lambda word, row: all(letter in row for letter in set(word.lower())) + return [word for word in words if any(is_in_row(word, row) for row in rows)] diff --git a/LeetCode/0532_K_diff_Pairs_in_an_Array.py b/LeetCode/0532_K_diff_Pairs_in_an_Array.py new file mode 100644 index 0000000..1e96cc0 --- /dev/null +++ b/LeetCode/0532_K_diff_Pairs_in_an_Array.py @@ -0,0 +1,14 @@ +from collections import Counter +class Solution: + def findPairs(self, nums: List[int], k: int) -> int: + ans = 0 + c = Counter(nums) + if k == 0: + for val in c.values(): + if val > 1: + ans += 1 + return ans + for i in c.keys(): + if i + k in c.keys(): + ans += 1 + return ans diff --git a/LeetCode/0551_ Student_Attendance_Record_I.py b/LeetCode/0551_ Student_Attendance_Record_I.py new file mode 100644 index 0000000..f11f0eb --- /dev/null +++ b/LeetCode/0551_ Student_Attendance_Record_I.py @@ -0,0 +1,20 @@ +class Solution: + def checkRecord(self, s: str) -> bool: + aCount = 0; + lCount = 0; + for ch in s: + if ch == "L": + lCount += 1 + else: + lCount = 0 + + if ch == "A": + aCount += 1 + + if lCount > 2: + return False + if aCount > 1: + return False + + return True + diff --git a/LeetCode/0561_Array_Partition_I.py b/LeetCode/0561_Array_Partition_I.py new file mode 100644 index 0000000..1743f89 --- /dev/null +++ b/LeetCode/0561_Array_Partition_I.py @@ -0,0 +1,3 @@ +class Solution: + def arrayPairSum(self, nums: List[int]) -> int: + return sum(sorted(nums)[::2]) \ No newline at end of file diff --git a/LeetCode/0567_Permutations_in_String.py b/LeetCode/0567_Permutations_in_String.py new file mode 100644 index 0000000..c8c03fb --- /dev/null +++ b/LeetCode/0567_Permutations_in_String.py @@ -0,0 +1,12 @@ +#Sliding Window Approach +from collections import Counter +class Solution: + def checkInclusion(self, s1, s2): + d1, d2 = Counter(s1), Counter(s2[:len(s1)]) + for start in range(len(s1), len(s2)): + if d1 == d2: return True + d2[s2[start]] += 1 + d2[s2[start-len(s1)]] -= 1 + if d2[s2[start-len(s1)]] == 0: + del d2[s2[start-len(s1)]] + return d1 == d2 \ No newline at end of file diff --git a/LeetCode/0589_Nary_Tree_Preorder_Traversal.py b/LeetCode/0589_Nary_Tree_Preorder_Traversal.py new file mode 100644 index 0000000..14035ce --- /dev/null +++ b/LeetCode/0589_Nary_Tree_Preorder_Traversal.py @@ -0,0 +1,15 @@ +class Solution(object): + def preorder(self, root): + """ + :type root: Node + :rtype: List[int] + """ + def traverse(root): + if not root: return + ret.append(root.val) + for child in root.children: + traverse(child) + + ret = [] + traverse(root) + return ret diff --git a/LeetCode/0599_Minimum_Index_Sum_of_Two_Lists.py b/LeetCode/0599_Minimum_Index_Sum_of_Two_Lists.py new file mode 100644 index 0000000..d43ce31 --- /dev/null +++ b/LeetCode/0599_Minimum_Index_Sum_of_Two_Lists.py @@ -0,0 +1,20 @@ +class Solution(object): + def findRestaurant(self, list1, list2): + ind1 = 0 + ind2 = 0 + ind_sum = sys.maxsize + rest = list() + + for restaurant1 in list1: + for restaurant2 in list2: + if (restaurant1 == restaurant2) and ((ind1 + ind2) < ind_sum): + ind_sum = ind1 + ind2 + rest = [] + rest.append(restaurant2) + elif (restaurant1 == restaurant2) and ((ind1 + ind2) == ind_sum): + rest.append(restaurant2) + ind2 = ind2 + 1 + ind1 = ind1 + 1 + ind2 = 0 + + return rest \ No newline at end of file diff --git a/LeetCode/0617_Merge_Two_Binary_Trees.py b/LeetCode/0617_Merge_Two_Binary_Trees.py new file mode 100644 index 0000000..feb8819 --- /dev/null +++ b/LeetCode/0617_Merge_Two_Binary_Trees.py @@ -0,0 +1,20 @@ +#Definition for a binary tree node. +#class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +class Solution: + def mergeTrees(self, t1, t2): + """ + :type t1: TreeNode + :type t2: TreeNode + :rtype: TreeNode + """ + if t1 is None: + return t2 + if t2 is not None: + t1.val += t2.val + t1.left = self.mergeTrees(t1.left, t2.left) + t1.right = self.mergeTrees(t1.right, t2.right) + return t1 diff --git a/LeetCode/0647_Palindromic_Substrings.py b/LeetCode/0647_Palindromic_Substrings.py new file mode 100644 index 0000000..d1f8b9e --- /dev/null +++ b/LeetCode/0647_Palindromic_Substrings.py @@ -0,0 +1,21 @@ +class Solution: + def countSubstrings(self, s: str) -> int: + N = len(s) + # declaring a DP matrix of size nxn + dp = [[0 for i in range(N)] for j in range(N)] + # looping through substring of every size and checking whether it is a valid substring + for l in range(N): + for i in range(N-l): + if l == 0: + dp[i][i] = 1 + continue + if s[i] == s[i+l]: + if l == 1: + dp[i][i+l] = 1 + elif dp[i+1][i+l-1] == 1: + dp[i][i+l] = 1 + count = 0 + for i in range(N): + for j in range(N): + count+=dp[i][j] + return count \ No newline at end of file diff --git a/LeetCode/0654_Maximum_Binary_Tree.py b/LeetCode/0654_Maximum_Binary_Tree.py new file mode 100644 index 0000000..6fc4128 --- /dev/null +++ b/LeetCode/0654_Maximum_Binary_Tree.py @@ -0,0 +1,13 @@ +class Solution: + def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode: + def helper(nums, root): + if not nums: + return None + if nums: + root = TreeNode(max(nums)) + ind=nums.index(max(nums)) + root.left= helper(nums[:ind],root) + root.right=helper(nums[ind+1:],root) + return root + root=TreeNode(0) + return helper(nums,root) diff --git a/LeetCode/0701_Insert_into_a_Binary_Search_Tree.py b/LeetCode/0701_Insert_into_a_Binary_Search_Tree.py new file mode 100644 index 0000000..0ddd84f --- /dev/null +++ b/LeetCode/0701_Insert_into_a_Binary_Search_Tree.py @@ -0,0 +1,34 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right + +def solve(r,k): + x = TreeNode(k) + ans = r + if(not r): + return x + while(r and (r.left or r.right) ): + if(r.val < k): + if(r.right): + r = r.right + else: + r.right = x + return ans + else: + if(r.left): + r = r.left + else: + r.left = x + return ans + if(r.val < k): + r.right = x + else: + r.left = x + return ans + +class Solution: + def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode: + return solve(root,val) diff --git a/LeetCode/0728_Self_Dividing_Numbers.py b/LeetCode/0728_Self_Dividing_Numbers.py new file mode 100644 index 0000000..af5a2f0 --- /dev/null +++ b/LeetCode/0728_Self_Dividing_Numbers.py @@ -0,0 +1,10 @@ +class Solution: + def selfDividingNumbers(self, left: int, right: int) -> List[int]: + result = [] + for i in range(left, right+1): + for char in str(i): + if int(char)==0 or i % int(char)!=0: + break + else: + result.append(i) + return result \ No newline at end of file diff --git a/LeetCode/0746_Min_Cost_Climbing_Stairs.py b/LeetCode/0746_Min_Cost_Climbing_Stairs.py new file mode 100644 index 0000000..30ffd1b --- /dev/null +++ b/LeetCode/0746_Min_Cost_Climbing_Stairs.py @@ -0,0 +1,16 @@ +class Solution: + def minCostClimbingStairs(self, cost: List[int]) -> int: + l=len(cost) + + if l<=2: + return 0 + a=[0]*l + a[0]=cost[0] + a[1]=cost[1] + for i in range(2,l): + a[i]=min(a[i-1],a[i-2])+cost[i] + return min(a[l-1],a[l-2]) + + + + \ No newline at end of file diff --git a/LeetCode/0771_Jewels_and_Stones.py b/LeetCode/0771_Jewels_and_Stones.py new file mode 100644 index 0000000..f635dcc --- /dev/null +++ b/LeetCode/0771_Jewels_and_Stones.py @@ -0,0 +1,8 @@ +class Solution: + def numJewelsInStones(self, J: str, S: str) -> int: + stones = Counter(S) + count = 0 + for j in J: + if stones and j in stones: + count += stones[j] + return count diff --git a/LeetCode/0832_Flipping_an_Image.py b/LeetCode/0832_Flipping_an_Image.py new file mode 100644 index 0000000..cfbe118 --- /dev/null +++ b/LeetCode/0832_Flipping_an_Image.py @@ -0,0 +1,11 @@ +class Solution: + def flipAndInvertImage(self, A: List[List[int]]) -> List[List[int]]: + for row in A: + for i in range(int((len(row) + 1) / 2)): + """ + In Python, the shortcut row[~i] = row[-i-1] = row[len(row) - 1 - i] + helps us find the i-th value of the row, counting from the right. + """ + row[i], row[~i] = row[~i] ^ 1, row[i] ^ 1 + return A + \ No newline at end of file diff --git a/LeetCode/0859_Buddy_String.py b/LeetCode/0859_Buddy_String.py new file mode 100644 index 0000000..55695c9 --- /dev/null +++ b/LeetCode/0859_Buddy_String.py @@ -0,0 +1,24 @@ +class Solution: + def buddyStrings(self, A: str, B: str) -> bool: + if len(A) != len(B): + return False + char_count = {} + indexes_to_swap = [] + dup = False + for idx, string in enumerate(A): + curr_char_count = char_count.get(string, 0) + curr_char_count += 1 + char_count[string] = curr_char_count + if (curr_char_count > 1): + dup = True + if string != B[idx]: + indexes_to_swap.append(idx) + if len(indexes_to_swap) > 2: + return False + + if len(indexes_to_swap) == 1: + return False + + if len(indexes_to_swap) == 2: + return A[indexes_to_swap[0]] == B[indexes_to_swap[1]] and A[indexes_to_swap[1]] == B[indexes_to_swap[0]] + return dup diff --git a/LeetCode/0867_Transpose_Matrix.py b/LeetCode/0867_Transpose_Matrix.py new file mode 100644 index 0000000..97fed72 --- /dev/null +++ b/LeetCode/0867_Transpose_Matrix.py @@ -0,0 +1,27 @@ +""" +Problem: Given a matrix A, return the transpose of A. The transpose of a matrix is the matrix flipped over it's main diagonal, switching the row and column indices of the matrix. + +Sample input: + [[1,2,3], + [4,5,6], + [7,8,9]] + +Sample output: + [[1,4,7], + [2,5,8], + [3,6,9]] +""" + +class Solution: + def transpose(self, A: List[List[int]]) -> List[List[int]]: + transpose=[] + k=0 + for p in range(len(A[0])): + temp=[] + for i in A: + while k List[int]: + total_a = sum(A) + total_b = sum(B) + set_b = set(B) + for candy in A: + swap_item = candy + (total_b - total_a) / 2 + if swap_item in set_b: + return [candy, candy + (total_b - total_a) / 2] \ No newline at end of file diff --git a/LeetCode/0891_Sum_of_Subsequence_Widths.py b/LeetCode/0891_Sum_of_Subsequence_Widths.py new file mode 100644 index 0000000..f355b2e --- /dev/null +++ b/LeetCode/0891_Sum_of_Subsequence_Widths.py @@ -0,0 +1,10 @@ +class Solution(object): + def sumSubseqWidths(self, A: List[int]) -> int: + ret_int = 0 + A_len = len(A) + A.sort(key=lambda x: int(x), reverse=True) + + for x in range(A_len): + ret_int += A[x] * (2**(A_len - x - 1) - 2**(x)) + + return ret_int % (10**9 + 7) diff --git a/LeetCode/0929_Unique_Email_Addresses.py b/LeetCode/0929_Unique_Email_Addresses.py new file mode 100644 index 0000000..55b5510 --- /dev/null +++ b/LeetCode/0929_Unique_Email_Addresses.py @@ -0,0 +1,11 @@ +class Solution: + def numUniqueEmails(self, emails: List[str]) -> int: + seen_emails = set() + for item in emails: + name, domain = item.split('@') + special_index = name.find('+') + if special_index != -1: + name = name[: special_index] + seen_emails.add(name.replace('.', '') + '@' + domain) + return len(seen_emails) + \ No newline at end of file diff --git a/LeetCode/0938_Range_Sum_of_BST.py b/LeetCode/0938_Range_Sum_of_BST.py new file mode 100644 index 0000000..3db83d4 --- /dev/null +++ b/LeetCode/0938_Range_Sum_of_BST.py @@ -0,0 +1,15 @@ +class Solution: + def __init__(self): + self.ans = 0 + + def rangeSumBST(self, root: TreeNode, L: int, R: int) -> int: + def dfs(node): + if node: + if L <= node.val <= R: + self.ans += node.val + if L < node.val: + dfs(node.left) + if node.val < R: + dfs(node.right) + dfs(root) + return self.ans diff --git a/LeetCode/0942_DI_String_Match.py b/LeetCode/0942_DI_String_Match.py new file mode 100644 index 0000000..60eeb14 --- /dev/null +++ b/LeetCode/0942_DI_String_Match.py @@ -0,0 +1,13 @@ +class Solution: + def diStringMatch(self, S: str) -> List[int]: + mx = 0 + mn = 0 + res = [0] * (len(S) + 1) + for i in range(len(S)): + if S[i] == "I": + res[i + 1] = mx + 1 + mx += 1 + else: + res[i + 1] = mn - 1 + mn -= 1 + return [x - mn for x in res] diff --git a/LeetCode/0973_ K_Closest_Points_to_Origin.py b/LeetCode/0973_ K_Closest_Points_to_Origin.py new file mode 100644 index 0000000..445b56f --- /dev/null +++ b/LeetCode/0973_ K_Closest_Points_to_Origin.py @@ -0,0 +1,28 @@ +from heapq import heappop, heappush +from typing import List, Tuple + + +class Solution: + def closest_points(self, points: List[Tuple[float, float]], k: int) -> List[Tuple[float, float]]: + """ + Finds the K points closest to the origin. + + The implementation pushes the points on a Heap with their key being the distance to the origin, then removes K elements from the heap. + I chose to go with a more verbose implementation to show how it can be done, but alternatively one could do: + + >>> from heapq import nsmallest + ... nsmallest(k, points, key=self.distance) + """ + + heap = [] + for point in points: + heappush(heap, (self.distance(point), point)) + + return [heappop(heap)[1] for _ in range(k)] + + def distance(self, point: Tuple[float, float]) -> float: + """ + Pythagorean formula to get the distance to the origin. + """ + + return (point[0] ** 2 + point[1] ** 2) ** 0.5 diff --git a/LeetCode/0995_Minimum_Number_of_K_Consecutive_Bit_Flips.py b/LeetCode/0995_Minimum_Number_of_K_Consecutive_Bit_Flips.py new file mode 100644 index 0000000..0ec30ef --- /dev/null +++ b/LeetCode/0995_Minimum_Number_of_K_Consecutive_Bit_Flips.py @@ -0,0 +1,18 @@ +class Solution: + def minKBitFlips(self, A: List[int], K: int) -> int: + n = len(A) + flips = [0]*(n+1); ans = 0 + for i in range(n): + flips[i] += flips[i-1] if i > 0 else 0 + + if not A[i] ^ (flips[i]%2): + if i + K - 1 >= n : + print(i, K) + return -1 + ans += 1 + flips[i] += 1 + flips[i+K] -= 1 + + return ans + + \ No newline at end of file diff --git a/LeetCode/0997_Find_The_Town_Judge.py b/LeetCode/0997_Find_The_Town_Judge.py new file mode 100644 index 0000000..37e928f --- /dev/null +++ b/LeetCode/0997_Find_The_Town_Judge.py @@ -0,0 +1,21 @@ +class Solution: + def findJudge(self, N: int, trust: List[List[int]]) -> int: + m=len(trust) + if 1==N: + if 0==m: + return 1 + tmp={} + dic={} + for i in range(m): + tmp[trust[i][0]]=1 + for i in range(m): + if trust[i][1] not in tmp: + if trust[i][1] not in dic: + dic[trust[i][1]]=1 + else: + dic[trust[i][1]]+=1 + for key in dic: + if N-1==dic[key]: + return key + return -1 + diff --git a/LeetCode/1009_Complement_of_base_10_integer.py b/LeetCode/1009_Complement_of_base_10_integer.py new file mode 100644 index 0000000..6ec5c64 --- /dev/null +++ b/LeetCode/1009_Complement_of_base_10_integer.py @@ -0,0 +1,11 @@ +class Solution: + def bitwiseComplement(self, N: int) -> int: + binary = bin(N)[2:] + ans = ['0'] * len(binary) + for i in range(len(binary)): + if binary[i] == '0': + ans[i] = '1' + else: + ans[i] = '0' + return int(''.join(ans), 2) + diff --git a/LeetCode/1018_Binary_Tree_Prefix_Divisible_By_5.py b/LeetCode/1018_Binary_Tree_Prefix_Divisible_By_5.py new file mode 100644 index 0000000..41d97ee --- /dev/null +++ b/LeetCode/1018_Binary_Tree_Prefix_Divisible_By_5.py @@ -0,0 +1,12 @@ +class Solution(object): + def prefixesDivBy5(self, A): + """ + :type A: List[int] + :rtype: List[bool] + """ + prev = 0 + for i in range(len(A)): + prev = 2 * prev + A[i] + A[i] = prev % 5 == 0 + return A + diff --git a/LeetCode/1023_Camelcase_Matching.py b/LeetCode/1023_Camelcase_Matching.py new file mode 100644 index 0000000..479cc5b --- /dev/null +++ b/LeetCode/1023_Camelcase_Matching.py @@ -0,0 +1,35 @@ +import re + +class Solution: + def camelMatch(self, queries: List[str], pattern: str) -> List[bool]: + p = re.findall('[A-Z][^A-Z]*', pattern) + result = [] + + for x in queries: + y = re.findall('[A-Z][^A-Z]*', x) + if len(p) != len(y): + result.append(False) + + else: + q = [] + + for i in range(len(p)): + t = 'false' + pi = p[i] + c = len(pi) + ct = 0 + + for j in y[i]: + if j == pi[ct]: + ct += 1 + if ct == c: + t = 'true' + break + q.append(t) + + k = True + if "false" in q: + k = False + + result.append(k) + return result diff --git a/LeetCode/1046_Last Stone Weight.py b/LeetCode/1046_Last Stone Weight.py new file mode 100644 index 0000000..9a955e4 --- /dev/null +++ b/LeetCode/1046_Last Stone Weight.py @@ -0,0 +1,26 @@ +import bisect +class Solution: + def lastStoneWeight(self, stones: List[int]) -> int: + stones.sort() + + l=len(stones) + while l>1: + + if stones[l-1]==stones[l-2]: + stones.pop() + stones.pop() + l=l-2 + else: + x=stones[l-1]-stones[l-2] + + stones.pop() + stones.pop() + bisect.insort(stones,x) + l-=1 + try: + return stones[0] + except: + return 0 + + + \ No newline at end of file diff --git a/LeetCode/1053_Previous_Permutation_With_One_Swap.py b/LeetCode/1053_Previous_Permutation_With_One_Swap.py new file mode 100644 index 0000000..6241c10 --- /dev/null +++ b/LeetCode/1053_Previous_Permutation_With_One_Swap.py @@ -0,0 +1,21 @@ +class Solution: + def prevPermOpt1(self, A: List[int]) -> List[int]: + a_length = len(A) + largest_left_index = 0 + largest_left = A[0] + for i in range(2, a_length + 1): + i *= -1 + if A[i] > A[i + 1]: + largest_left_index = i + largest_left = A[i] + break + + largest_right_index = 0 + largest_right = 0 + for i in range(a_length + largest_left_index + 1, a_length): + if A[i] > largest_right and A[i] < largest_left: + largest_right_index = i + largest_right = A[i] + + A[largest_left_index], A[largest_right_index] = A[largest_right_index], A[largest_left_index] + return A diff --git a/LeetCode/1103_Distributing_Candies_to_people.py b/LeetCode/1103_Distributing_Candies_to_people.py new file mode 100644 index 0000000..bc3b8cf --- /dev/null +++ b/LeetCode/1103_Distributing_Candies_to_people.py @@ -0,0 +1,23 @@ +def distributeCandies(self, candies: int, num_people: int) -> List[int]: + sum1, rounds, temp = sum(range(1, num_people + 1)), 0, candies + # 1. get the number of rounds that will go through the array + while temp > 0: + temp -= sum1 + rounds * num_people ** 2 + rounds += 1 + rounds -= 1 + result = [0] * num_people + # 2. add up the number until right before the final round + if rounds > 0: + for i in range(1, num_people + 1): + result[i - 1] = (2 * i + (rounds - 1) * num_people) * rounds // 2 + candies -= result[i - 1] + base_num = num_people * rounds + # 3. add the final round of numbers + for i in range(1, num_people + 1): + if candies <= base_num + i: + result[i - 1] += candies + break + else: + result[i - 1] += base_num + i + candies -= base_num + i + return result \ No newline at end of file diff --git a/LeetCode/1108_Defanging_an_IP_Address.py b/LeetCode/1108_Defanging_an_IP_Address.py new file mode 100644 index 0000000..bdd37a7 --- /dev/null +++ b/LeetCode/1108_Defanging_an_IP_Address.py @@ -0,0 +1,3 @@ +class Solution: + def defangIPaddr(self, address: str) -> str: + return(address.replace('.','[.]')) diff --git a/LeetCode/1137_N_th_Tribonacci_Number.py b/LeetCode/1137_N_th_Tribonacci_Number.py new file mode 100644 index 0000000..8c01a86 --- /dev/null +++ b/LeetCode/1137_N_th_Tribonacci_Number.py @@ -0,0 +1,14 @@ +class Solution: + def tribonacci(self, n: int) -> int: + a, b, c = 0, 1, 1 + if n == 0: + return 0 + elif n == 1 or n == 2: + return 1 + else: + for _ in range(n - 2): + temp = a + b + c + a = b + b = c + c = temp + return temp diff --git a/LeetCode/1160_FindWordsThatCanBeFormedByCharacters.py b/LeetCode/1160_FindWordsThatCanBeFormedByCharacters.py new file mode 100644 index 0000000..f45bab0 --- /dev/null +++ b/LeetCode/1160_FindWordsThatCanBeFormedByCharacters.py @@ -0,0 +1,23 @@ +class Solution: + def countCharacters(self, words: List[str], chars: str) -> int: + charBins = {char:chars.count(char) for char in chars} + goodWords = [] + + for word in words: + if (len(word) > len(chars)): + continue + + if not set(word).issubset(chars): + continue + + letterBins = {letter:word.count(letter) for letter in word} + + goodWord = True + for letter in letterBins: + if letterBins[letter] > charBins[letter]: + goodWord = False + + if (goodWord): + goodWords.append(word) + + return sum(len(word) for word in goodWords) diff --git a/LeetCode/1189_Maximum_Number_of_Balloons.py b/LeetCode/1189_Maximum_Number_of_Balloons.py new file mode 100644 index 0000000..805eaf3 --- /dev/null +++ b/LeetCode/1189_Maximum_Number_of_Balloons.py @@ -0,0 +1,12 @@ +class Solution(object): + def maxNumberOfBalloons(self, text) -> int: + """ + :type text: str + :rtype: int + """ + a_count = text.count("b") + b_count = text.count("a") + l_count = text.count("l") / 2 + o_count = text.count("o") / 2 + n_count = text.count("n") + return int(min([a_count,b_count,l_count,o_count,n_count])) \ No newline at end of file diff --git a/LeetCode/1219_path_with_maximum_gold.py b/LeetCode/1219_path_with_maximum_gold.py new file mode 100644 index 0000000..d8d1e5d --- /dev/null +++ b/LeetCode/1219_path_with_maximum_gold.py @@ -0,0 +1,22 @@ +class Solution: + def getMaximumGold(self, grid): + def bfs(i, j): + stack = [(grid[i][j], i, j, set([(i, j)]))] + while stack: + temp = [] + for cur, i, j, p in stack: + if cur > self.res: + self.res = cur + self.best_res = p + for x, y in [[i + 1, j], [i - 1, j], [i, j + 1], [i, j - 1]]: + if 0 <= x < m and 0 <= y < n and grid[x][y] and (x, y) not in p: + temp.append((cur + grid[x][y], x, y, p | {(x, y)})) + stack = temp + m, n = len(grid), len(grid[0]) + self.res = 0 + self.best_res = set() + for row in range(m): + for col in range(n): + if grid[row][col] and (row, col) not in self.best_res: + bfs(row, col) + return self.res diff --git a/LeetCode/1221_Split_ a_String_in_Balanced_Strings.py b/LeetCode/1221_Split_ a_String_in_Balanced_Strings.py new file mode 100644 index 0000000..676979f --- /dev/null +++ b/LeetCode/1221_Split_ a_String_in_Balanced_Strings.py @@ -0,0 +1,13 @@ +class Solution: + def balancedStringSplit(self, s: str) -> int: + r= 0 + l = 0 + count = 0 + for i in range(len(s)): + if s[i] == "R": + r += 1 + else: + l += 1 + if r == l: + count += 1 + return count diff --git a/LeetCode/1249_Minimum_Remove_to_Make_Valid_Parentheses.py b/LeetCode/1249_Minimum_Remove_to_Make_Valid_Parentheses.py new file mode 100644 index 0000000..b53b968 --- /dev/null +++ b/LeetCode/1249_Minimum_Remove_to_Make_Valid_Parentheses.py @@ -0,0 +1,28 @@ +class Solution: + def minRemoveToMakeValid(self, s: str) -> str: + + stackparen = [] + stackindex = [] + result = '' + result1 = '' + i = 0 + j = 0 + + while i <= len(s) - 1: + if s[i] == ')' and len(stackparen) == 0: + i += 1 + continue + if s[i] == '(': + stackparen.append(s[i]) + stackindex.append(j) + if s[i] == ')' and len(stackparen) > 0: + stackparen.pop() + stackindex.pop() + result += s[i] + j += 1 + i += 1 + + for j, i in enumerate(result): + if j not in stackindex: + result1 += result[j] + return result1 diff --git a/LeetCode/1250_Check_If_It_Is_a_Good_Array.py b/LeetCode/1250_Check_If_It_Is_a_Good_Array.py new file mode 100644 index 0000000..0673d1c --- /dev/null +++ b/LeetCode/1250_Check_If_It_Is_a_Good_Array.py @@ -0,0 +1,15 @@ +class Solution(object): + def isGoodArray(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + def gcd(a, b): + if a == 0: + return b + if a > b: + return gcd(b, a) + return gcd(b % a, a) + + return reduce(gcd, nums) == 1 + diff --git a/LeetCode/1252_Cells_with_Odd_Values_in_a_Matrix.py b/LeetCode/1252_Cells_with_Odd_Values_in_a_Matrix.py new file mode 100644 index 0000000..c6dba68 --- /dev/null +++ b/LeetCode/1252_Cells_with_Odd_Values_in_a_Matrix.py @@ -0,0 +1,13 @@ +import numpy as np + +class Solution: + + def get_summation_matrix(self, n: int, m: int, ri: int, ci: int): + mat = np.zeros([n, m], dtype=int) + mat[ri,:] += 1 + mat[:,ci] += 1 + return mat + + def oddCells(self, n: int, m: int, indices: List[List[int]]) -> int: + matrix_inc = sum(self.get_summation_matrix(n, m, ri, ci) for ri, ci in indices) + return np.count_nonzero(matrix_inc % 2 == 1) diff --git a/LeetCode/1281_Subtract_the_Product_and_Sum_of_Digits_of_an_Integer.py b/LeetCode/1281_Subtract_the_Product_and_Sum_of_Digits_of_an_Integer.py new file mode 100644 index 0000000..5fbfa4b --- /dev/null +++ b/LeetCode/1281_Subtract_the_Product_and_Sum_of_Digits_of_an_Integer.py @@ -0,0 +1,10 @@ +class Solution: + def subtractProductAndSum(self, n: int) -> int: + a = 1 + b = 0; + while(n): + a*=n%10 + b+=n%10 + n//=10 + return a - b + diff --git a/LeetCode/1282_Group_People_Given_the_Group_Size_They_Belong_To.py b/LeetCode/1282_Group_People_Given_the_Group_Size_They_Belong_To.py new file mode 100644 index 0000000..a257644 --- /dev/null +++ b/LeetCode/1282_Group_People_Given_the_Group_Size_They_Belong_To.py @@ -0,0 +1,12 @@ +class Solution: + def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]: + maxGroupSize= max(groupSizes) + groups = [[] for i in range(maxGroupSize)] + + for i, p in enumerate(groupSizes): + groups[p-1].append(i) + if len(groups[p-1]) == p: + groups.append(groups[p-1]) + groups[p-1] = [] + + return groups[maxGroupSize:] diff --git a/LeetCode/1288_Remove_Covered_Intervals.py b/LeetCode/1288_Remove_Covered_Intervals.py new file mode 100644 index 0000000..143dc05 --- /dev/null +++ b/LeetCode/1288_Remove_Covered_Intervals.py @@ -0,0 +1,11 @@ +class Solution: + def removeCoveredIntervals(self, intervals: List[List[int]]) -> int: + intervals.sort(key=lambda x: (x[0], -x[1])) + inside = 0 + right = -1 + for i, j in intervals: + if j <= right: + inside += 1 + else: + right = j + return len(intervals) - inside diff --git a/LeetCode/1299_Replace_Elements_with_Greatest_Elements_on_Right_Side.py b/LeetCode/1299_Replace_Elements_with_Greatest_Elements_on_Right_Side.py new file mode 100644 index 0000000..f3134cf --- /dev/null +++ b/LeetCode/1299_Replace_Elements_with_Greatest_Elements_on_Right_Side.py @@ -0,0 +1,8 @@ +class Solution(object): + def replaceElements(self, arr): + for i in range(len(arr)): + if i==len(arr)-1: + arr[i] = -1 + else: + arr[i] = max(arr[i+1:]) + return arr \ No newline at end of file diff --git a/LeetCode/1340_Jump_Game_V.py b/LeetCode/1340_Jump_Game_V.py new file mode 100644 index 0000000..837a615 --- /dev/null +++ b/LeetCode/1340_Jump_Game_V.py @@ -0,0 +1,22 @@ +class Solution: + def maxJumps(self, arr: List[int], d: int) -> int: + dp = [1] * len(arr) + + for i, _ in sorted(enumerate(arr), key=lambda x: x[1]): + max_h = 0 + for j in range(i - 1, max(i - d - 1, -1), -1): + max_h = max(max_h, arr[j]) + if max_h < arr[i]: + dp[i] = max(dp[i], dp[j] + 1) + else: + break + + max_h = 0 + for j in range(i + 1, min(i + d + 1, len(arr))): + max_h = max(max_h, arr[j]) + if max_h < arr[i]: + dp[i] = max(dp[i], dp[j] + 1) + else: + break + + return max(dp) diff --git a/LeetCode/1346_Check_if_N_and_its_Double_Exist.py b/LeetCode/1346_Check_if_N_and_its_Double_Exist.py new file mode 100644 index 0000000..1abe45b --- /dev/null +++ b/LeetCode/1346_Check_if_N_and_its_Double_Exist.py @@ -0,0 +1,9 @@ +class Solution: + def checkIfExist(self, arr: List[int]) -> bool: + + seen = set() + for x in arr: + if x * 2 in seen or (not x % 2 and x // 2 in seen): + return True + seen.add(x) + return False diff --git a/LeetCode/1351_Count_Negative_Numbers_in_Sorted_Matrix.py b/LeetCode/1351_Count_Negative_Numbers_in_Sorted_Matrix.py new file mode 100644 index 0000000..54b9947 --- /dev/null +++ b/LeetCode/1351_Count_Negative_Numbers_in_Sorted_Matrix.py @@ -0,0 +1,11 @@ +class Solution: + def countNegatives(self, grid: List[List[int]]) -> int: + count = 0 + for row in grid: + for index in range(len(row)-1, -1, -1): + if row[index] < 0: + count += 1 + else: + break + + return count \ No newline at end of file diff --git a/LeetCode/1365_How_Many_Numbers_Are_Smaller_Than_the_Current_Number.py b/LeetCode/1365_How_Many_Numbers_Are_Smaller_Than_the_Current_Number.py new file mode 100644 index 0000000..bb892a0 --- /dev/null +++ b/LeetCode/1365_How_Many_Numbers_Are_Smaller_Than_the_Current_Number.py @@ -0,0 +1,10 @@ +class Solution: + def smallerNumbersThanCurrent(self, nums: List[int]) -> List[int]: + ans = [] + for i in range(0, len(nums)): + soln = 0 + for j in range(0, len(nums)): + if(nums[j] < nums[i] and j != i): + soln += 1 + ans. append(soln) + return ans \ No newline at end of file diff --git a/LeetCode/1374_Generate_a_String_With_Characters_That_Have_Odd_Counts.py b/LeetCode/1374_Generate_a_String_With_Characters_That_Have_Odd_Counts.py new file mode 100644 index 0000000..3f8c607 --- /dev/null +++ b/LeetCode/1374_Generate_a_String_With_Characters_That_Have_Odd_Counts.py @@ -0,0 +1,10 @@ +class Solution: + def generateTheString(self, n: int) -> str: + ans=[] + if n%2==0: + ans=['x' for i in range(n-1)] + ans.append('y') + else: + ans=['x' for i in range(n)] + return ans + \ No newline at end of file diff --git a/LeetCode/1380_Lucky_Numbers_in_a_Matrix.py b/LeetCode/1380_Lucky_Numbers_in_a_Matrix.py new file mode 100644 index 0000000..44570a6 --- /dev/null +++ b/LeetCode/1380_Lucky_Numbers_in_a_Matrix.py @@ -0,0 +1,8 @@ +class Solution: + def luckyNumbers (self, matrix: List[List[int]]) -> List[int]: + min_n = {min(rows) for rows in matrix} + max_n = {max(columns) for columns in zip(*matrix)} + + return list(min_n & max_n) + + \ No newline at end of file diff --git a/LeetCode/1402_Reducing_Dishes.py b/LeetCode/1402_Reducing_Dishes.py new file mode 100644 index 0000000..1f2c012 --- /dev/null +++ b/LeetCode/1402_Reducing_Dishes.py @@ -0,0 +1,11 @@ +class Solution: + def maxSatisfaction(self, satisfaction: List[int]) -> int: + + satisfaction.sort(reverse=True) + ans = cur_sum = 0 + for ele in satisfaction: + cur_sum += ele + if cur_sum >= 0: + ans += cur_sum + + return ans; \ No newline at end of file diff --git a/LeetCode/1431_Kids_With_the_Greatest_Number_of_Candies.py b/LeetCode/1431_Kids_With_the_Greatest_Number_of_Candies.py new file mode 100644 index 0000000..c6b81b6 --- /dev/null +++ b/LeetCode/1431_Kids_With_the_Greatest_Number_of_Candies.py @@ -0,0 +1,11 @@ +class Solution: + def kidsWithCandies(self, candies: List[int], extraCandies: int) -> List[bool]: + m=max(candies) + t=m-extraCandies + output=[] + for i in candies: + if i List[str]: + res = [] + j = 0 + for i in range(1,n+1): + res.append("Push") + if i == target[j]: + j += 1 + else: + res.append("Pop") + if j == len(target): + break + return res \ No newline at end of file diff --git a/LeetCode/1446_consecutive_characters.py b/LeetCode/1446_consecutive_characters.py new file mode 100644 index 0000000..c29914c --- /dev/null +++ b/LeetCode/1446_consecutive_characters.py @@ -0,0 +1,10 @@ +class Solution: + def maxPower(self, s: str) -> int: + maxlen,currlen=1,1 + for i in range(1,len(s)): + if(s[i]==s[i-1]): + currlen=currlen+1 + maxlen=max(maxlen,currlen) + else: + currlen=1 + return maxlen \ No newline at end of file diff --git a/LeetCode/1460_Make_Two_Arrays_Equal_by_Reversing_Sub_Arrays.py b/LeetCode/1460_Make_Two_Arrays_Equal_by_Reversing_Sub_Arrays.py new file mode 100644 index 0000000..831907b --- /dev/null +++ b/LeetCode/1460_Make_Two_Arrays_Equal_by_Reversing_Sub_Arrays.py @@ -0,0 +1,5 @@ +from collections import Counter + +class Solution: + def canBeEqual(self, target: List[int], arr: List[int]) -> bool: + return Counter(target) == Counter(arr) \ No newline at end of file diff --git a/LeetCode/1464_Maximum_Product_Of_Two_Elements_In_An_Array.py b/LeetCode/1464_Maximum_Product_Of_Two_Elements_In_An_Array.py new file mode 100644 index 0000000..c1fcb8f --- /dev/null +++ b/LeetCode/1464_Maximum_Product_Of_Two_Elements_In_An_Array.py @@ -0,0 +1,4 @@ +class Solution: + def maxProduct(self, nums: List[int]) -> int: + nums.sort() + return (nums[-1]-1) * (nums[-2]-1) \ No newline at end of file diff --git a/LeetCode/1470_Shuffle_The_Array.py b/LeetCode/1470_Shuffle_The_Array.py new file mode 100644 index 0000000..0892eb7 --- /dev/null +++ b/LeetCode/1470_Shuffle_The_Array.py @@ -0,0 +1,13 @@ +class Solution: + def shuffle(self, nums: List[int], n: int) -> List[int]: + shuffled_list = [0]*(2*n) + left_index = 0 + right_index = n + for index in range(0, 2*n): + if index%2 == 0: + shuffled_list[index] = nums[left_index] + left_index += 1 + else: + shuffled_list[index] = nums[right_index] + right_index += 1 + return shuffled_list diff --git a/LeetCode/1499_Max_Value_of_Equation.py b/LeetCode/1499_Max_Value_of_Equation.py new file mode 100644 index 0000000..4c1f330 --- /dev/null +++ b/LeetCode/1499_Max_Value_of_Equation.py @@ -0,0 +1,23 @@ +class Solution(object): + def findMaxValueOfEquation(self, points, k): + """ + :type points: List[List[int]] + :type k: int + :rtype: int + """ + ans = None + + d = deque() + for x, y in points: + while len(d) > 0 and d[0][0] < x - k: + d.popleft() + + if len(d) != 0: + ans = max(ans, x + y + d[0][1] - d[0][0]) + + while (len(d) != 0) and d[-1][1] - d[-1][0] < y - x: + d.pop() + + d.append((x, y)) + + return ans diff --git a/LeetCode/1512_Number_of_Good_Pairs.py b/LeetCode/1512_Number_of_Good_Pairs.py new file mode 100644 index 0000000..f0eafe2 --- /dev/null +++ b/LeetCode/1512_Number_of_Good_Pairs.py @@ -0,0 +1,8 @@ +class Solution: + def numIdenticalPairs(self, nums: List[int]) -> int: + ans = 0 + for i in range(0, len(nums)): + for j in range(0, len(nums)): + if(nums[i] == nums[j] and i < j): + ans += 1 + return ans \ No newline at end of file diff --git a/LeetCode/1518_Water_Bottles.py b/LeetCode/1518_Water_Bottles.py new file mode 100644 index 0000000..d6544e5 --- /dev/null +++ b/LeetCode/1518_Water_Bottles.py @@ -0,0 +1,26 @@ +class Solution(object): + def numWaterBottles(self, numBottles, numExchange): + """ + :type numBottles: int + :type numExchange: int + :rtype: int + """ + full = numBottles + empty = 0 + drank = 0 + + while True: + # 1. Drink + empty += full + drank += full + full = 0 + + # 2. Exchange + while empty >= numExchange: + empty -= numExchange + full += 1 + + if not full: + break + + return drank diff --git a/LeetCode/1544_Make_string_great.py b/LeetCode/1544_Make_string_great.py new file mode 100644 index 0000000..be04276 --- /dev/null +++ b/LeetCode/1544_Make_string_great.py @@ -0,0 +1,18 @@ +def finder(s): + a =0 + for i in range(len(s) -1): + if abs(ord(s[i]) - ord(s[i+1])) == 32 : + del s[i] + del s[i] + a =1 + break + if a == 0 : + return s + else: + return finder(s) + +class Solution: + def makeGood(self, s: str) -> str: + s = list(s) + h = finder(s) + return ("".join(h)) \ No newline at end of file diff --git a/LeetCode/1550_Three_Consecutive_Odds.py b/LeetCode/1550_Three_Consecutive_Odds.py new file mode 100644 index 0000000..cc99bea --- /dev/null +++ b/LeetCode/1550_Three_Consecutive_Odds.py @@ -0,0 +1,3 @@ +class Solution: + def threeConsecutiveOdds(self, arr: List[int]) -> bool: + return '111' in "".join([str(i%2) for i in arr]) \ No newline at end of file diff --git a/LeetCode/1556_Thousand_Separator.py b/LeetCode/1556_Thousand_Separator.py new file mode 100644 index 0000000..ef46674 --- /dev/null +++ b/LeetCode/1556_Thousand_Separator.py @@ -0,0 +1,5 @@ +class Solution: + def thousandSeparator(self, n: int) -> str: + num = n + ans = f'{num:,}'.replace(',', '.') + return ans diff --git a/LeetCode/1559_Detect_Cycles_In_2D_Grid.py b/LeetCode/1559_Detect_Cycles_In_2D_Grid.py new file mode 100644 index 0000000..92985e3 --- /dev/null +++ b/LeetCode/1559_Detect_Cycles_In_2D_Grid.py @@ -0,0 +1,55 @@ +class Solution: + def __init__(self): + self.directionX = [-1,0,1,0] + self.directionY = [0,1,0,-1] + def isValid(self, x, y, N, M): + if x < N and x >= 0 and y < M and y >= 0: + return True + return False + + def isCycle(self, x, y, arr, visited, parentX, parentY): + # Mark the current vertex as visited + visited[x][y] = True + N, M = len(arr), len(arr[0]) + + for k in range(4): + newX = x + self.directionX[k] + newY = y + self.directionY[k] + if self.isValid(newX, newY, N, M) and arr[newX][newY] == arr[x][y] and not (parentX == newX and parentY == newY): + if visited[newX][newY]: + return True + else: + + check = self.isCycle(newX, newY, arr, visited, x,y) + if check: + return True + return False + + def containsCycle(self, grid: List[List[str]]) -> bool: + N, M = len(grid), len(grid[0]) + # Initially all the cells are unvisited + visited = [[False] * M for _ in range(N)] + + # Variable to store the result + cycle = False + + # As there is no fixed position of the cycle + # we have to loop through all the elements + for i in range(N): + if cycle == True: + break + + for j in range(M): + ## Taking (-1, -1) as source node's parent + if visited[i][j] == False: + cycle = self.isCycle(i, j, grid, visited, -1, -1) + + if cycle == True: + break + + return cycle + + + + + \ No newline at end of file diff --git a/LeetCode/1582_SpecialPositionsInABinaryMatrix.py b/LeetCode/1582_SpecialPositionsInABinaryMatrix.py new file mode 100644 index 0000000..221aab6 --- /dev/null +++ b/LeetCode/1582_SpecialPositionsInABinaryMatrix.py @@ -0,0 +1,22 @@ +class Solution(object): + def numSpecial(self, mat): + """ + :type mat: List[List[int]] + :rtype: int + """ + numSpecial = 0 + + for a in range(len(mat)): + for b in range(len(mat[a])): + if mat[a][b] == 1: + valid = True + for c in range(len(mat[a])): + if mat[a][c] != 0 and c != b: + valid = False + if valid: + for d in range(len(mat)): + if mat[d][b] != 0 and d != a: + valid = False + if valid: + numSpecial+=1 + return numSpecial \ No newline at end of file diff --git a/LeetCode/1588_SumOfAllOddLengthSubarrays.py b/LeetCode/1588_SumOfAllOddLengthSubarrays.py new file mode 100644 index 0000000..f689d7a --- /dev/null +++ b/LeetCode/1588_SumOfAllOddLengthSubarrays.py @@ -0,0 +1,15 @@ +class Solution(object): + def sumOddLengthSubarrays(self, arr): + + _sum = 0 + length = len(arr) + sub_len = 1 + start = 0 + + while sub_len <= length: + for start in range(length - sub_len + 1): + for i in range(start, start + sub_len): + _sum = _sum + arr[i] + sub_len = sub_len + 2 + + return _sum \ No newline at end of file diff --git a/LeetCode/1589-maximum-sum-obtained-of-any-permutation.py b/LeetCode/1589-maximum-sum-obtained-of-any-permutation.py new file mode 100644 index 0000000..4037231 --- /dev/null +++ b/LeetCode/1589-maximum-sum-obtained-of-any-permutation.py @@ -0,0 +1,46 @@ +import itertools + + +class Solution(object): + def maxSumRangeQuery(self, nums, requests): + """ + :type nums: List[int] + :type requests: List[List[int]] + :rtype: int + """ + def addmod(a, b, mod): # avoid overflow in other languages + a %= mod + b %= mod + if mod-a <= b: + b -= mod + return a+b + + def mulmod(a, b, mod): # avoid overflow in other languages + a %= mod + b %= mod + if a < b: + a, b = b, a + result = 0 + while b > 0: + if b%2 == 1: + result = addmod(result, a, mod) + a = addmod(a, a, mod) + b //= 2 + return result + + MOD = 10**9+7 + + count = [0]*len(nums) + for start, end in requests: + count[start] += 1 + if end+1 < len(count): + count[end+1] -= 1 + for i in range(1, len(count)): + count[i] += count[i-1] + nums.sort() + count.sort() + result = 0 + for i, (num, c) in enumerate(zip(nums, count)): + # result = addmod(result, mulmod(num, c, MOD), MOD) + result = (result+num*c)%MOD + return result diff --git a/LeetCode/1592_Rearrange_Spaces_Between_Words.py b/LeetCode/1592_Rearrange_Spaces_Between_Words.py new file mode 100644 index 0000000..cca6c53 --- /dev/null +++ b/LeetCode/1592_Rearrange_Spaces_Between_Words.py @@ -0,0 +1,9 @@ +class Solution: + def reorderSpaces(self, text: str) -> str: + words = text.split() + space_cnt = text.count(' ') + + if len(words) == 1: + return words[0] + ' ' * space_cnt + else: + return (' '* (space_cnt // (len(words)-1))).join(words)+ ' ' * (space_cnt % (len(words)-1)) \ No newline at end of file diff --git a/LeetCode/1598_Crawler_Log_Folder.py b/LeetCode/1598_Crawler_Log_Folder.py new file mode 100644 index 0000000..411aab2 --- /dev/null +++ b/LeetCode/1598_Crawler_Log_Folder.py @@ -0,0 +1,13 @@ +class Solution: + def minOperations(self, logs: List[str]) -> int: + cnt = 0 + for log in logs: + if log == "../": + if cnt != 0: + cnt -= 1 + continue + elif log == "./": + continue + else: + cnt += 1 + return cnt if cnt > 0 else 0 diff --git a/LeetCode/1599_Maximum_Profit_of_Operating_a_Centennial_Wheel.py b/LeetCode/1599_Maximum_Profit_of_Operating_a_Centennial_Wheel.py new file mode 100644 index 0000000..29c19dc --- /dev/null +++ b/LeetCode/1599_Maximum_Profit_of_Operating_a_Centennial_Wheel.py @@ -0,0 +1,39 @@ +class Solution(object): + def minOperationsMaxProfit(self, customers, boardingCost, runningCost) : + """ + :type customers: List[int] + :type boardingCose: int + :type runningCose: int + :rtype: int + """ + wait = 0 + pro = 0 + high = 0 + res = -1 + for i in range(len(customers)): + vacc = 4 - wait + if vacc <= 0: + wait += customers[i] - 4 + pro += 4 * boardingCost - runningCost + # board all + elif customers[i] <= vacc: # board=customers[i]+wait + pro += boardingCost * (customers[i] + wait) - runningCost + wait = 0 + else: + pro += boardingCost * 4 - runningCost + wait += customers[i] - 4 + if pro > high: + high = pro + res = i + # determine after all arrives + pro_per = boardingCost * 4 - runningCost + if pro_per > 0: + last = wait % 4 + if wait >= 4: + if boardingCost * last - runningCost > 0: + return len(customers) + wait // 4 + 1 + else: + return len(customers) + wait // 4 + if boardingCost * last - runningCost > 0: + return len(customers) + 1 + return res + 1 if res >= 0 else -1 diff --git a/LeetCode/1603_Design_Parking_System.py b/LeetCode/1603_Design_Parking_System.py new file mode 100644 index 0000000..cbba789 --- /dev/null +++ b/LeetCode/1603_Design_Parking_System.py @@ -0,0 +1,11 @@ +class ParkingSystem: + + def __init__(self, big: int, medium: int, small: int): + self._limits = [big, medium, small] + + + def addCar(self, carType: int) -> bool: + self._limits[carType - 1] -= 1 + if self._limits[carType - 1] < 0: + return False + return True diff --git a/LeetCode/1604_Alert_Using_Same_Key_Card_Three_or_More_Times_in_a_One_Hour_Period.py b/LeetCode/1604_Alert_Using_Same_Key_Card_Three_or_More_Times_in_a_One_Hour_Period.py new file mode 100644 index 0000000..afd7763 --- /dev/null +++ b/LeetCode/1604_Alert_Using_Same_Key_Card_Three_or_More_Times_in_a_One_Hour_Period.py @@ -0,0 +1,35 @@ +class Solution(object): + def alertNames(self, keyName, keyTime): + """ + :type keyName: List[str] + :type keyTime: List[str] + :rtype: List[str] + """ + mapp = {} + for i in range(len(keyName)): + name = keyName[i] + if(name not in mapp): + mapp[name] = [keyTime[i]] + else: + mapp[name].append(keyTime[i]) + res = [] + for name, arr in mapp.items(): + arr.sort() + for i in range(len(arr)-2): + time= arr[i] + t2 = arr[i+1] + t3 = arr[i+2] + if(time[0:2]=="23"): + endTime = "24:00" + if(t2<=endTime and t3<=endTime and t2>time and t3>time): + res.append(name) + break + else: + start = int(time[0:2]) + endTime = str(start+1)+time[2:] + if(start<9): + endTime = "0"+endTime + if(t2<=endTime and t3<=endTime): + res.append(name) + break + return sorted(res) diff --git a/LeetCode/1605_Find_Valid_Matrix_Given_Row_and_Column_Sums.py b/LeetCode/1605_Find_Valid_Matrix_Given_Row_and_Column_Sums.py new file mode 100644 index 0000000..5631572 --- /dev/null +++ b/LeetCode/1605_Find_Valid_Matrix_Given_Row_and_Column_Sums.py @@ -0,0 +1,13 @@ +class Solution: + def restoreMatrix(self, rowSum: List[int], colSum: List[int]) -> List[List[int]]: + m = len(rowSum) + n = len(colSum) + matrix = [[0]*n for i in range(m)] + print(matrix) + for i in range(m): + for j in range(n): + matrix[i][j] = min(rowSum[i],colSum[j]) + rowSum[i] -= matrix[i][j] + colSum[j] -= matrix[i][j] + return matrix + \ No newline at end of file diff --git a/LeetCode/1606_Find_Servers_That_Handled_Most_Number_of_Requests.py b/LeetCode/1606_Find_Servers_That_Handled_Most_Number_of_Requests.py new file mode 100644 index 0000000..73d5a08 --- /dev/null +++ b/LeetCode/1606_Find_Servers_That_Handled_Most_Number_of_Requests.py @@ -0,0 +1,36 @@ +class Solution(object): + def busiestServers(self, k, arrival, load): + """ + :type k: int + :type arrival: List[int] + :type load: List[int] + :rtype: List[int] + """ + from sortedcontainers import SortedList + avail = SortedList() + for i in range(k): + avail.add(i) + h = [] + count = [0]*k + for i in range(len(arrival)): + s = arrival[i] + e = arrival[i]+load[i] + while h and h[0][0]<=s: + _, j = heappop(h) + avail.add(j) + if len(h)==k: + continue + si = avail.bisect_left(i%k) + if si==len(avail): + ser = avail[0] + else: + ser = avail[si] + avail.remove(ser) + count[ser]+=1 + heappush(h, (e, ser)) + maxReq = max(count) + ans = [] + for i in range(len(count)): + if count[i]==maxReq: + ans.append(i) + return ans diff --git a/LeetCode/1608_Special_Array_With_X_Elements_Greater_Than_or_Equal_x.py b/LeetCode/1608_Special_Array_With_X_Elements_Greater_Than_or_Equal_x.py new file mode 100644 index 0000000..630f5cd --- /dev/null +++ b/LeetCode/1608_Special_Array_With_X_Elements_Greater_Than_or_Equal_x.py @@ -0,0 +1,14 @@ +class Solution(object): + def specialArray(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + nums.sort() + out = -1 + for i in range(len(nums)): + if nums[~i]>=i+1: + if i==len(nums)-1 or nums[~(i+1)] int: + b = list(bin(n)[2:]) + temp = len(b) + for i in range(1, temp): + b[i] = str(int(b[i]) ^ int(b[i-1])) + return int(''.join(b), 2) diff --git a/README.md b/README.md index b724687..491214d 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,9 @@ If there is no Issue joined in the PR your PR will be labeld as **spam** and clo If your code don't passes the Check on LeetCode.com your PR will be labeld as **"invalid"** and the Issue stays open for the next PR! If your PR doesn' follow the Contributing Guidelines of this Repository it will be also marked as **spam** and closed! +### Spam Users +Users who spam this Repo with PRs/Issues that does not align the Contribution Guidelines will be **blocked**. + ## Getting Started * Fork this repository (Click the Form button, top right of this page) * Clone your fork down to your local machine @@ -73,6 +76,18 @@ git push origin branch-name ## Which PR will be accepted? * Ones you are assigned to * Your PR has to link the Issue -* Your Solution must be correct - you can check ist on LeetCode (submit) if it works on different test-cases +* Your Solution must be correct - you can check first on LeetCode (submit) if it works on different test-cases + +## Which PRs will be NOT accepted? +* Ones you are NOT assigned to +* Your PR is NOT linked to the Issue you are linked to +* Your Solution is not correct +* Your PR contains more than the .py file +* PRs that "correct" Typos or spam files with comments +* PRs that "correct" Coding Styles - Please accept that everybody has a different style + +## Hacktoberfest 2020 +During October there come pretty much PRs and Issues - Please be patient because of my fulltime job I cannot be online 24/7 - I do my best to work through your PRs as soon as possible. +This Repository is open for **Hacktoberfest 2020 ONLY**! No PRs/Issues for Hacktoberfest 2021 or later will be accepted and marked as **invalid/spam** __Thank You!__ diff --git a/leetcodeChecker.py b/leetcodeChecker.py new file mode 100644 index 0000000..181a6e3 --- /dev/null +++ b/leetcodeChecker.py @@ -0,0 +1,311 @@ +import requests, os, re, json, time +from bs4 import BeautifulSoup +from github import Github +from dotenv import load_dotenv + +load_dotenv() +#load_dotenv(dotenv_path='sample.env') + +LC_BASE = 'https://leetcode.com' +LC_CSRF = LC_BASE + '/ensure_csrf/' +LC_LOGIN = LC_BASE + '/accounts/login/' +LC_GRAPHQL = LC_BASE + '/graphql' +LC_CATEGORY_PROBLEMS = LC_BASE + '/api/problems/{category}' +LC_PROBLEM = LC_BASE + '/problems/{slug}/description' +LC_TEST = LC_BASE + '/problems/{slug}/interpret_solution/' +LC_SUBMIT = LC_BASE + '/problems/{slug}/submit/' +LC_SUBMISSIONS = LC_BASE + '/api/submissions/{slug}' +LC_SUBMISSION = LC_BASE + '/submissions/detail/{submission}/' +LC_CHECK = LC_BASE + '/submissions/detail/{submission}/check/' +LC_PROBLEM_SET_ALL = LC_BASE + '/problemset/all/' +LC_PROGRESS_ALL = LC_BASE + '/api/progress/all/' + +def _break_code_lines(s): + return s.replace('\r\n', '\n').replace('\xa0', ' ').split('\n') + +def _break_paragraph_lines(s): + lines = _break_code_lines(s) + result = [] + # reserve one and only one empty line between two non-empty lines + for line in lines: + if line.strip() != '': # a line with only whitespaces is also empty + result.append(line) + result.append('') + return result + + +def _remove_description(code): + eod = code.find('[End of Description]') + if eod == -1: + return code + eol = code.find('\n', eod) + if eol == -1: + return '' + return code[eol+1:] + +def _split(s): + if isinstance(s, list): + lines = [] + for element in s: + lines.extend(_split(element)) + return lines + + # Replace all \r\n to \n and all \r (alone) to \n + s = s.replace('\r\n', '\n').replace('\r', '\n').replace('\0', '\n') + # str.split has an disadvantage that ''.split('\n') results in [''], but what we want + # is []. This small function returns [] if `s` is a blank string, that is, containing no + # characters other than whitespaces. + if s.strip() == '': + return [] + return s.split('\n') + +def _make_headers(): + assert is_login() + headers = {'Origin': LC_BASE, + 'Referer': LC_BASE, + 'X-Requested-With': 'XMLHttpRequest', + 'X-CSRFToken': session.cookies.get('csrftoken', '')} + return headers + +def get_progress(): + headers = _make_headers() + res = session.get(LC_PROGRESS_ALL, headers=headers) + if res.status_code != 200: + _echoerr('cannot get the progress') + return None + + data = res.json() + if 'solvedTotal' not in data: + return None + return data + +def _status_to_name(status): + if status == 10: + return 'Accepted' + if status == 11: + return 'Wrong Answer' + if status == 12: + return 'Memory Limit Exceeded' + if status == 13: + return 'Output Limit Exceeded' + if status == 14: + return 'Time Limit Exceeded' + if status == 15: + return 'Runtime Error' + if status == 16: + return 'Internal Error' + if status == 20: + return 'Compile Error' + if status == 21: + return 'Unknown Error' + return 'Unknown State' + + +def load_session_cookie(leetSession): + my_cookie = { + "version": 0, + "name": 'LEETCODE_SESSION', + "value": leetSession, + "port": None, + #"port_specified":False, + "domain": '.leetcode.com', + #"domain_specified":False, + #"domain_initial_dot":True, + "path": '/', + # "path_specified":True, + "secure": 1, + "expires": None, + "discard": True, + "comment": None, + "comment_url": None, + "rest": {}, + "rfc2109": False + } + + session_cookie = my_cookie + #session_cookie_raw = pickle.dumps(**my_cookie, protocol=0).decode('utf-8') + global session + session = requests.Session() + session.cookies.set(**session_cookie) + + progress = get_progress() + if progress is None: + keyring.delete_password('leetcode', 'SESSION_COOKIE') + return False + + return True + +def _check_result(submission_id): + + while True: + headers = _make_headers() + url = LC_CHECK.format(submission=submission_id) + res = session.get(url, headers=headers) + if res.status_code != 200: + _echoerr('cannot get the execution result') + return None + + r = res.json() + if r['state'] == 'SUCCESS': + prog_stage = 'Done ' + break + elif r['state'] == 'PENDING': + prog_stage = 'Pending ' + elif r['state'] == 'STARTED': + prog_stage = 'Running ' + + time.sleep(1) + + result = { + 'answer': r.get('code_answer', []), + 'runtime': r['status_runtime'], + 'state': _status_to_name(r['status_code']), + 'testcase': _split(r.get('input', r.get('last_testcase', ''))), + 'passed': r.get('total_correct') or 0, + 'total': r.get('total_testcases') or 0, + 'error': _split([v for k, v in r.items() if 'error' in k and v]) + } + + # the keys differs between the result of testing the code and submitting it + # for submission judge_type is 'large', and for testing judge_type does not exist + if r.get('judge_type') == 'large': + result['answer'] = _split(r.get('code_output', '')) + result['expected_answer'] = _split(r.get('expected_output', '')) + result['stdout'] = _split(r.get('std_output', '')) + result['runtime_percentile'] = r.get('runtime_percentile', '') + else: + # Test states cannot distinguish accepted answers from wrong answers. + if result['state'] == 'Accepted': + result['state'] = 'Finished' + result['stdout'] = _split(r.get('code_output', [])) + result['expected_answer'] = [] + result['runtime_percentile'] = r.get('runtime_percentile', '') + result['expected_answer'] = r.get('expected_code_answer', []) + return result + + +def submit_solution(slug, filetype, code=None): + assert is_login() + problem = get_problem(slug) + if not problem: + return None + + code = _remove_description(code) + + headers = _make_headers() + headers['Referer'] = LC_PROBLEM.format(slug=slug) + body = {'data_input': problem['testcase'], + 'lang': filetype, + 'question_id': str(problem['id']), + 'test_mode': False, + 'typed_code': code, + 'judge_type': 'large'} + url = LC_SUBMIT.format(slug=slug) + + res = session.post(url, json=body, headers=headers) + + if res.status_code != 200: + if 'too fast' in res.text: + print('you are sending the request too fast') + else: + print('cannot submit the solution for ' + slug) + return None + + result = _check_result(res.json()['submission_id']) + result['title'] = problem['title'] + return result + +def is_login(): + return session and 'LEETCODE_SESSION' in session.cookies + +def get_problem(slug): + assert is_login() + headers = _make_headers() + headers['Referer'] = LC_PROBLEM.format(slug=slug) + body = {'query': '''query getQuestionDetail($titleSlug : String!) { + question(titleSlug: $titleSlug) { + questionId + questionFrontendId + title + content + stats + difficulty + codeDefinition + sampleTestCase + enableRunCode + translatedContent + } +}''', + 'variables': {'titleSlug': slug}, + 'operationName': 'getQuestionDetail'} + res = session.post(LC_GRAPHQL, json=body, headers=headers) + if res.status_code != 200: + _echoerr('cannot get the problem: {}'.format(slug)) + return None + + q = res.json()['data']['question'] + content = q['translatedContent'] or q['content'] + if content is None: + _echoerr('cannot get the problem: {}'.format(slug)) + return None + + soup = BeautifulSoup(content, features='html.parser') + problem = {} + problem['id'] = q['questionId'] + problem['fid'] = q['questionFrontendId'] + problem['title'] = q['title'] + problem['slug'] = slug + problem['level'] = q['difficulty'] + problem['desc'] = _break_paragraph_lines(soup.get_text()) + problem['templates'] = {} + for t in json.loads(q['codeDefinition']): + problem['templates'][t['value']] = _break_code_lines(t['defaultCode']) + problem['testable'] = q['enableRunCode'] + problem['testcase'] = _split(q['sampleTestCase']) + stats = json.loads(q['stats']) + problem['total_accepted'] = stats['totalAccepted'] + problem['total_submission'] = stats['totalSubmission'] + problem['ac_rate'] = stats['acRate'] + return problem + + + +# load details from ENV +repo_name = os.getenv("REPO_NAME") +access_token = os.getenv("GITHUB_ACCESS_TOKEN") +pull_number = int(os.getenv("PR_NUMBER")) +leetcode_csrf_token = os.getenv("LEETCODE_CSRF_TOKEN") +leetcode_session_token = os.getenv("LEETCODE_SESSION_TOKEN") + +# authentication +g = Github(access_token) +repo = g.get_repo(repo_name) + +# get PR details +pull = repo.get_pull(pull_number) +all_files = pull.get_files() + +# get details of files from PR +file_url = "" +problem_name = "" +for i in all_files: + if i.filename[-3:] == ".py": + file_url = i.raw_url + problem_name = i.filename[9:].lower() + +# parse question id and problem name +question_id = int(problem_name[0:4]) +problem_name = re.sub("_", "-", problem_name[5:-3]) + +# get file code +r = requests.get(file_url) +code = r.text + +load_session_cookie(leetcode_session_token) +result = submit_solution(problem_name,'python3',code) +if result is None: + print("Nothing to do") +elif result['state'] == 'Finished': + pull.create_issue_comment("All test case have been passed, can be merged") +else: + pull.create_issue_comment(result['state']) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..455c38f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +requests==2.24.0 +bs4==0.0.1 +PyGithub==1.53 +python-dotenv==0.14.0 +