Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the solutions #1633

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions array_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# The code defines a productExceptSelf method to compute the product of all elements in an array except the current element, without using division.
# The result for each element at index 'i' is the product of all elements to the left of 'i' and all elements to the right of 'i'.

# Initial Setup:
# - A result array 'res' is initialized with ones. This will store the final product for each index.

# Prefix Pass:
# - We initialize a variable 'prefix' to keep track of the product of elements to the left of each index.
# - As we iterate over the array from left to right:
# - res[i] is set to 'prefix', which holds the cumulative product of all elements before 'i'.
# - 'prefix' is then updated by multiplying it with nums[i], moving the prefix product forward.

# Postfix Pass:
# - We initialize a variable 'postfix' to track the product of elements to the right of each index.
# - We iterate over the array from right to left:
# - res[i] is updated by multiplying it with 'postfix', giving the product of all elements except nums[i].
# - 'postfix' is then updated by multiplying it with nums[i], shifting the postfix product backward.

# Final Result:
# - After both passes, res contains the product of all elements except the current one for each index, which is returned.

# TC: O(n) - Each element is processed twice (once in the prefix pass and once in the postfix pass).
# SC: O(1) - The space complexity is constant as we only use a result array (considered output space) and two variables (prefix and postfix).


class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
res = [1] * (len(nums))

prefix = 1
for i in range(len(nums)):
res[i] = prefix
prefix *= nums[i]
postfix = 1
for i in range(len(nums) - 1, -1, -1):
res[i] *= postfix
postfix *= nums[i]
return res
66 changes: 66 additions & 0 deletions diagonal_traverse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# The code defines a findDiagonalOrder method to return all elements of a 2D matrix in diagonal order.
# Diagonal order involves traversing diagonals in an up-right and down-left zigzag pattern across the matrix.

# Step 1:
# - Initialize an empty list 'result' to store the elements in diagonal order.

# Step 2:
# - Retrieve the dimensions of the matrix (m for rows, n for columns).
# - Set initial indices i and j to 0 (starting at the top-left corner of the matrix).
# - Initialize 'direction' to 0, where 0 represents the up-right direction and 1 represents the down-left direction.

# Step 3:
# - Iterate m * n times, once for each element in the matrix:
# - Append the current element mat[i][j] to 'result'.
# - Determine movement based on the current 'direction':
# - If direction is 0 (up-right):
# - If we're at the last column (j == n - 1), move down by incrementing i and change direction to 1 (down-left).
# - If we're at the first row (i == 0), move right by incrementing j and change direction to 1.
# - Otherwise, move up-right by decrementing i and incrementing j.
# - If direction is 1 (down-left):
# - If we're at the last row (i == m - 1), move right by incrementing j and change direction to 0 (up-right).
# - If we're at the first column (j == 0), move down by incrementing i and change direction to 0.
# - Otherwise, move down-left by incrementing i and decrementing j.

# Step 4:
# - After traversing all elements, return the 'result' list containing the matrix elements in diagonal order.

# TC: O(m * n) - The time complexity is linear in the number of elements, as each element is accessed once.
# SC: O(1) - The space complexity is constant, excluding the output list, as only a few variables are used for control flow.


class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
# Step 1
result = []
# Step 2
m, n = len(mat), len(mat[0])
i = j = direction = 0

# Step 3
for _ in range(m * n):
result.append(mat[i][j])

if direction == 0: # Up-right direction
if j == n - 1:
direction = 1 # Change direction to down-left
i += 1
elif i == 0:
direction = 1 # Change direction to down-left
j += 1
else:
i -= 1
j += 1
else: # Down-left direction
if i == m - 1:
direction = 0 # Change direction to up-right
j += 1
elif j == 0:
direction = 0 # Change direction to up-right
i += 1
else:
i += 1
j -= 1

# Step 4
return result
46 changes: 46 additions & 0 deletions spiral.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# The code defines a spiralOrder method to traverse a 2D matrix in a spiral order and return the elements in the order they are visited.

# Initialization:
# - 'res' is an empty list to store the elements in spiral order.
# - 'directions' holds four possible movement directions: right (0,1), down (1,0), left (0,-1), and up (-1,0).
# - 'steps' is initialized with the number of steps for horizontal and vertical movements.
# - steps[0] represents the remaining steps for moving right/left (number of columns),
# - steps[1] represents the remaining steps for moving down/up (number of rows minus 1).
# - 'r' and 'c' are the starting row and column indices, initialized to start outside the first element to enable the first move.
# - 'd' is the direction index, starting at 0 for the initial rightward direction.

# Main Loop:
# - The loop continues as long as there are steps left in the current direction.
# - For each direction:
# - Move for the current number of steps in the current direction:
# - Update the row and column indices (r and c) according to the current direction.
# - Append the current element matrix[r][c] to 'res'.
# - After completing the steps in the current direction, decrease the step count for the current direction (steps[d & 1]).
# - Change direction by incrementing 'd' and taking modulo 4 to cycle back to the beginning after four directions (right, down, left, up).

# Final Result:
# - Once all elements have been visited, return the 'res' list containing the elements in spiral order.

# TC: O(m * n) - Each element in the matrix is visited exactly once.
# SC: O(1) - Excluding the output list, only a few variables are used for control, so the space complexity is constant.


from typing import List


class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
res = []
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
steps = [len(matrix[0]), len(matrix) - 1]

r, c, d = 0, -1, 0
while steps[d & 1]:
for i in range(steps[d & 1]):
r += directions[d][0]
c += directions[d][1]
res.append(matrix[r][c])
steps[d & 1] -= 1
d += 1
d %= 4
return res