diff --git a/Problem1.py b/Problem1.py new file mode 100644 index 00000000..bd184408 --- /dev/null +++ b/Problem1.py @@ -0,0 +1,27 @@ +#TC = O(n) since we are using only one array to store leftpass and then reusing the same array to generate the rightpass and the solution +#SC = O(1) +#Did this code successfully run on Leetcode : Yes +#approach:First, we do a left-to-right pass storing running products before each index. +#Then, we do a right-to-left pass multiplying the existing results with right-side products. +#This way, each element gets the product of all other elements without using division. + +from typing import List + + +class Solution: + def productExceptSelf(self, nums: List[int]) -> List[int]: + n = len(nums) + result = [0]*n + + rp = 1 + result [0]=1 #for leftpass we need to multiply the left number of i so for index 0 the left is empty thats why we initialize with 1 + #for left pass + for i in range(1,n): + rp = rp* nums[i-1] + result[i]=rp + #right pass but to decrease the SC we will be storing it in the left pass itself + rp = 1 #we again initilaize rp to 1 + for i in range (n-2,-1,-1): + rp = rp * nums[i+1] + result[i]=result[i]*rp + return result \ No newline at end of file diff --git a/Problem2.py b/Problem2.py new file mode 100644 index 00000000..b42d6914 --- /dev/null +++ b/Problem2.py @@ -0,0 +1,41 @@ +# Time Complexity: O(m*n), we visit every element in the matrix exactly once +# Space Complexity: O(1), only using a few variables, result array doesn't count as extra space +#Did this code successfully run on Leetcode :Yes +# We use a direction flag (True = UP-RIGHT, False = DOWN-LEFT) to track which way we are currently moving +# In each iteration we first collect the current element, then figure out the next position based on direction +# When we hit a wall, we step sideways (down or right) instead of continuing and flip the direction + +class Solution: + def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]: + m = len(mat) # number of rows + n = len(mat[0]) # number of columns + result = [0] * (m * n) # output array with m*n slots initialized to 0 + row = column = 0 # start at top-left corner (row=0, col=0) + direction = True # True = going UP-RIGHT, False = going DOWN-LEFT + + for i in range(m * n): # loop once for every element in the matrix + result[i] = mat[row][column] # collect current element into result + + if direction: # currently going UP-RIGHT + if column == n - 1: # hit the RIGHT wall, can't go right + row += 1 # step DOWN instead + direction = False # flip to DOWN-LEFT + elif row == 0: # hit the TOP wall, can't go up + column += 1 # step RIGHT instead + direction = False # flip to DOWN-LEFT + else: # no wall hit, free to move UP-RIGHT + column += 1 # move right + row -= 1 # move up + + else: # currently going DOWN-LEFT + if row == m - 1: # hit the BOTTOM wall, can't go down + column += 1 # step RIGHT instead + direction = True # flip to UP-RIGHT + elif column == 0: # hit the LEFT wall, can't go left + row += 1 # step DOWN instead + direction = True # flip to UP-RIGHT + else: # no wall hit, free to move DOWN-LEFT + column -= 1 # move left + row += 1 # move down + + return result \ No newline at end of file diff --git a/Problem3.py b/Problem3.py new file mode 100644 index 00000000..25d4216d --- /dev/null +++ b/Problem3.py @@ -0,0 +1,34 @@ +# Time Complexity: O(m*n), we visit every element in the matrix exactly once +# Space Complexity: O(1), we only use 4 boundary variables, result array doesn't count as extra space +# We use 4 boundaries (top, bottom, left, right) to track the unvisited region of the matrix +# In each while loop iteration, we walk all 4 sides of the current boundary and shrink each wall inward after walking it +# We add if checks before bottom and left walks to avoid revisiting elements when only a single row or column remains + +class Solution: + def spiralOrder(self, matrix): + m = len(matrix) # number of rows + n = len(matrix[0]) # number of columns + top, bottom, left, right = 0, m - 1, 0, n - 1 # initialize all 4 boundaries + result = [] # output list to store spiral order elements + + while top <= bottom and left <= right: # keep going while valid region exists + + for i in range(left, right + 1): # walk RIGHT across top row + result.append(matrix[top][i]) # pick element at row=top, col=i + top += 1 # shrink top boundary downward + + for i in range(top, bottom + 1): # walk DOWN right column + result.append(matrix[i][right]) # pick element at row=i, col=right + right -= 1 # shrink right boundary leftward + + if top <= bottom: # check if a bottom row still exists + for i in range(right, left - 1, -1): # walk LEFT across bottom row + result.append(matrix[bottom][i]) # pick element at row=bottom, col=i + bottom -= 1 # shrink bottom boundary upward + + if left <= right: # check if a left column still exists + for i in range(bottom, top - 1, -1): # walk UP left column + result.append(matrix[i][left]) # pick element at row=i, col=left + left += 1 # shrink left boundary rightward + + return result \ No newline at end of file