Skip to content
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
54 changes: 54 additions & 0 deletions Problem1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## Problem 1
# https://leetcode.com/problems/product-of-array-except-self/
# Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].

# Example:

# Input: [1,2,3,4]
# Output: [24,12,8,6]
# Note: Please solve it without division and in O(n).

# Follow up:
# Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)

class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
"""
Logic:
To find the product of all elements except the one at the current index,
we can calculate the product of all elements to the left of the index
and multiply it by the product of all elements to the right of the index.

Time Complexity: O(n)
We iterate through the array of length `n` exactly twice (once forward,
once backward). Both passes take O(n) time, resulting in an overall
linear time complexity.

Space Complexity: O(1) auxiliary space
The problem explicitly states that the output array `result` does not
count towards the extra space complexity. We only use a few integer
variables (`rp`, `n`), making the auxiliary space complexity O(1).
"""
rp = 1
n = len(nums)

# Initialize the result array with 1s
result = [1 for _ in range(n)]

# First pass (Left to Right):
# Calculate the product of all elements to the LEFT of index i
for i in range(1, n):
rp = rp * nums[i - 1] # Running product of left elements
result[i] = rp # Store the left product in result[i]

# Reset running product for the right side pass
rp = 1

# Second pass (Right to Left):
# Calculate the product of all elements to the RIGHT of index i
# and multiply it directly with the existing left product in result[i]
for i in range(n - 2, -1, -1):
rp = rp * nums[i + 1] # Running product of right elements
result[i] = result[i] * rp # Multiply left product by right product

return result
84 changes: 84 additions & 0 deletions Problem2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
## Problem 2
# https://leetcode.com/problems/diagonal-traverse/
# Given a matrix of M x N elements (M rows, N columns), return all elements of the matrix in diagonal order as shown in the below image.

# Example:

# Input:

# [

# [ 1, 2, 3 ],

# [ 4, 5, 6 ],

# [ 7, 8, 9 ]

# ]

# Output: [1,2,4,7,5,3,6,8,9]

class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
"""
Logic:
We simulate the diagonal traversal by keeping track of our current row (r),
column (c), and the direction we are moving (isGoingUp).

For each step, we first add the current element to our result array.
Then, we determine the next coordinates based on our current direction:

1. Moving UP-RIGHT (isGoingUp = True):
- If we hit the right boundary (c == numCols - 1), we move down to the next row (r += 1) and change direction.
- If we hit the top boundary (r == 0), we move right to the next column (c += 1) and change direction.
- Otherwise, we just keep going up-right (r -= 1, c += 1).

2. Moving DOWN-LEFT (isGoingUp = False):
- If we hit the bottom boundary (r == numRows - 1), we move right (c += 1) and change direction.
- If we hit the left boundary (c == 0), we move down (r += 1) and change direction.
- Otherwise, we just keep going down-left (r += 1, c -= 1).

Time Complexity: O(M * N)
Where M is the number of rows and N is the number of columns in the matrix.
We visit every single element in the matrix exactly once to build the result array.

Space Complexity: O(1) auxiliary space
We are only using a few variable pointers (`r`, `c`, `isGoingUp`, `numRows`, `numCols`).
The space required for the output array `result` is typically not counted towards
the auxiliary space complexity in these types of problems.
"""
if not mat or not mat[0]:
return []

numRows, numCols = len(mat), len(mat[0])
result = [0] * (numRows * numCols)

r, c = 0, 0
isGoingUp = True

for i in range(numRows * numCols):
result[i] = mat[r][c]

# Determine the next cell based on the current direction
if isGoingUp:
if c == numCols - 1: # Hit right edge: move down, go left
isGoingUp = False
r += 1
elif r == 0: # Hit top edge: move right, go left
isGoingUp = False
c += 1
else: # Normal up-right move
r -= 1
c += 1
else:
if r == numRows - 1: # Hit bottom edge: move right, go up
isGoingUp = True
c += 1
elif c == 0: # Hit left edge: move down, go up
isGoingUp = True
r += 1
else: # Normal down-left move
r += 1
c -= 1

return result
70 changes: 70 additions & 0 deletions Problem3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# ## Problem 3
# https://leetcode.com/problems/spiral-matrix/
# Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

# Example 1:

# Input:

# [

# [ 1, 2, 3 ],

# [ 4, 5, 6 ],

# [ 7, 8, 9 ]

# ]
# Output: [1,2,3,6,9,8,7,4,5]
# Example 2:

# Input:

# [

# [1, 2, 3, 4],

# [5, 6, 7, 8],

# [9,10,11,12]

# ]
# Output: [1,2,3,4,8,12,11,10,9,5,6,7]


# Time Complexity: O(m * n)
# Space Complexity: O(1)
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
m = len(matrix)
n = len(matrix[0])
left, top = 0, 0
right, bottom = n - 1, m - 1
result = []

while left <= right and top <= bottom:
# 1. Traverse from Left to Right along the Top row
for i in range(left, right + 1):
result.append(matrix[top][i])
top += 1

# 2. Traverse from Top to Bottom along the Right column
for i in range(top, bottom + 1):
result.append(matrix[i][right])
right -= 1

# Make sure we are now on a different row
if top <= bottom:
# 3. Traverse from Right to Left along the Bottom row
for i in range(right, left - 1, -1):
result.append(matrix[bottom][i])
bottom -= 1

# Make sure we are now on a different column
if left <= right:
# 4. Traverse from Bottom to Top along the Left column
for i in range(bottom, top - 1, -1):
result.append(matrix[i][left])
left += 1

return result