0% found this document useful (0 votes)
30 views30 pages

Dsa 50 Udemy

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views30 pages

Dsa 50 Udemy

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

TOPI Ques Question - Long Link Hint Solution

C tion -
Short
D ARR Sorte You are given an Array is Sorted. Two Pointer approach. class Solution(object):
Squares of
A AY d array of Integers in a Sorted
Find the maxmimum squared number def sortedSquares(self, nums):
Y1 Squar which each Array -of left and rightmost element. Keep res = [0]*len(nums)
ed subsequent value is LeetCode
the max element in the result array left = 0
Array not less than the until the left meets right right = idx = len(nums) - 1
previous value. Write while(left <= right):
a function that takes if(nums[left]**2 > nums[right]**2):
res[idx] = nums[left]**2
this array as an input
left += 1
and returns a new
else:
array with the res[idx] = nums[right]**2
squares of each right -= 1
number sorted in idx -= 1
ascending order. return res
D ARR Mon An array is Monotonic Array should be Either increasing or class Solution(object):
A AY otoni monotonic if it is Array - decreasing. Check the left and def isMonotonic(self, nums):
Y1 c either monotone LeetCode rightmost element to find it is length = len(nums) #3
Array increasing or decreasing or not. If decreasing, None left = nums[0] #1
monotone of the next element should be greater right = nums[length - 1] #2
decreasing. An array than the current element. decrease = True
is monotone if left < right: #1<2
decrease = False #false
increasing if all its
if(decrease):
elements from left to
for i in range(length - 1):
right are non- if(nums[i] < nums[i+1]):
decreasing. An array return False
is monotone else:
decreasing if all its for i in range(length - 1): #0,1
elements from left to if(nums[i] > nums[i+1]):
right are non- return False
increasing. Given an return True
integer array return
true if the given
array is monotonic,
or false otherwise.
D ARR Rotat Given an array, Rotate Right Rotation : Reverse Entire Array, class Solution(object):
A AY e rotate the array to Array - Reverse from 0 to k - 1, Reverse from k
Y2 Array the right by k steps, LeetCode to length -1 def reverse(self, nums, start, end):
where k is non- Left Rotation : Reverse from 0 to k - 1, while(start < end):
negative. Reverse from k to length -1, Reverse nums[start], nums[end] = nums[end], nums[start]
Entire Array start += 1
end -= 1

def rotate(self, nums, k):


length = len(nums)
k = k % length
self.reverse(nums, 0, length-1)
self.reverse(nums, 0, k - 1)
self.reverse(nums, k, length - 1)
print(nums)
D ARR Conta You are given an Container Brute Force => O(N²) time with O(1) class Solution(object):
A AY iner integer array height With Most space ==> Two Pointer approach def maxArea(self, height):
Y2 with of length n. There Water - Let the maxArea be 0. Start with left left = 0
most are n vertical lines LeetCode and right most element. Caluculate the right = len(height) - 1
Wate drawn such that the current area with the width and the maxArea = 0
r two endpoints of the minimum height of two elements.
ith line are (i, 0) and Update the maxArea with the while left <= right:
width = right - left
(i, height[i]). maximum of it and current area. Until
minHeight = min(height[left], height[right])
Find two lines that left crosses right.
currArea = minHeight * width
together with the x- maxArea = max(currArea, maxArea)
axis form a if(height[left] < height[right]):
container, such that left += 1
the container else:
contains the most right -= 1
water(depth is return maxArea
constant across
containers). Return
the area(that the 2
lines and the X axis
make) of container
which can store the
max amount of
water. Notice that
you may not slant
the container.
D HAS Two You are given an Two Sum - Brute Force => O(N²) time with O(1) class Solution:
A H Sum array of Integers and LeetCode space ==> Hashmap with O(N) time def twoSum(self, nums: List[int], target: int) -> List[int]:
Y3 TAB another integer and O(N) space. map = {}
LE targetValue. Write a Create a hashmap to maintain visited for i in range(len(nums)):
function that will items and store its respective index. compliment = target - nums[i]
take these inputs and Search for the compliment value inside if compliment in map:
return the indices of Hashmap, if found return the current return [i,map[compliment]]
else:
the 2 integers in the index and index of the compliment
map[nums[i]] = i
array that add up from hahmap else put the index of the
return []
targetValue. visited item.
D HAS Isom Given two strings s Isomorphic If S and T are of different lengths, class Solution(object):
A H orphi and t, determine if Strings - return Fasle. def isIsomorphic(self, s, t):
Y3 TAB c they are isomorphic. LeetCode Create two Maps for S and T if(len(s) != len(t)):
LE String Two strings s and t respectively. Iterate over each return False
s are isomorphic if the element. If s[i] is in sMap and It is not sMap = {}
characters in s can be equal to t[i] return false and vice versa. tMap = {}
replaced to get t. Else return True. for i in range(len(s)):
if(s[i] in sMap):
All occurrences of a
if(sMap[s[i]] != t[i]):
character must be
return False
replaced with else:
another character sMap[s[i]] = t[i]
while preserving the if(t[i] in tMap):
order of characters. if(tMap[t[i]] != s[i]):
No two characters return False
may map to the else:
same character, but tMap[t[i]] = s[i]
a character may map return True
to itself. s and t
consist of any valid
ascii character.
D REC Fibon In the Fibonacci Fibonacci Recursively add fib(n-1) and fib(n-2). class Solution:
A URSI acci sequence, each Number - To avoid calling same function twice, def fib(self, n: int) -> int:
Y4 ON subsequent term is LeetCode memoize with map storing the number map = {
obtained by adding and its corresponding fibonaaci 0: 0,
the preceding 2 number. If the number is in hashmap, 1: 1
terms. This is true for Don't call fib function }
all the numbers if n in map:
return map[n]
except the first 2
else:
numbers of the
map[n] = self.fib(n-1) + self.fib(n-2)
Fibonacci series as return map[n]
they do not have 2
preceding numbers.
The first 2 terms in
the Fibonacci series
is 0 and 1. F(n) = F(n-
1)+F(n-2) for n>1.
Write a function that
finds F(n) given n
where n is an integer
greater than equal to
0. For the first term n
= 0.
D REC Powe Let’s define a https: Iterate over each element of the array, def powerSum(array, power = 1):
A URSI r Sum peculiar type of array //replit. If the element is an array or list, sum = 0
Y4 ON in which each com/@001 recursively call powerSum with the for i in array:
element is either an AakashAak same array but the power if type(i) == list:
integer or another ash/Python incremented by 1. And sum up the sum += powerSum(i, power + 1)
peculiar array. #powerSu output with the sum. else:
Assume that a m.py Return sum^power sum += i
return sum ** power
peculiar array is
never empty. Write a
array = [1, 2, [3,4], [[2]]]
function that will print(powerSum(array))
take a peculiar array
as its input and find
the sum of its
elements. If an array
is an element in the
peculiar array you
have to convert it to
it’s equivalent value
so that you can sum
it with the other
elements. Equivalent
value of an array is
the sum of its
elements raised to
the number which
represents how far
nested it is. For e.g.
[2,3[4,1,2]] = 2+3+
(4+1+2)^2
[1,2,[7,[3,4],2]] = 1 +
2 +( 7+(3+4)^3+2)^2
D REC Perm Given an array of Permutatio Maintain Two indices i and j. Iterate class Solution(object):
A URSI utati distinct integers, ns - the array with j from i to len(array). def permute(self, nums):
Y5 ON ons return all the LeetCode swap the array[i] with arra[j] and permutations = []
possible recursively call the function by def helper(nums, i):
permutations. You incrementing i. and reswap again. If i if(i == len(nums) - 1):
can return the reached the end, push the copy of the permutations.append(nums[:])
answer in any order. array to the result. Return result at return
for j in range(i, len(nums)):
last. This will form a decision tree like
nums[i], nums[j] = nums[j], nums[i]
structure. Time complexity is O(N * N!)
helper(nums, i+1)
. Space is O(N). nums[i], nums[j] = nums[j], nums[i]
helper(nums, 0)
return permutations
D REC Powe Given an integer Subsets - Iterate over the entire array, At each class Solution(object):
A URSI r Set array of unique LeetCode element we can make 2 decisions. def subsets(self, nums):
y5 ON elements, return all Either to add that element in the array result = []
possible subsets (the or leave It. Call the Helper(nums = def helper(nums, i, subset):
power set). The given array, idx = 0, subset = []), when if(i == len(nums)):
solution set must not the idx reaches the length of the array, result.append(subset[:])
contain duplicate append the copy of the subset to the return
helper(nums, i+1, subset)
subsets. Return the output. Else make a decision of not
subset.append(nums[i])
solution in any order. adding the element Helper(nums, idx
helper(nums, i+1, subset)
+= 1, subset), and add the element to subset.pop()
the subset.append(nums[i]) and call helper(nums, 0, [])
Helper(nums, idx += 1) and pop from return result
subset. Return the ouput. Time and
space ==> O(2ⁿ * N/2)
D STRI Non You are given a string First Iterate over each character of the class Solution(object):
A NG repea consisting of only Unique string. Maintain a Hashmap, If the map def firstUniqChar(self, s):
Y6 ting lower case and Character contains the char as key and its value sMap = {}
chara upper-case English in a String - is 1, return its index. Else put the char for i in range(len(s)):
cter Alphabets and LeetCode inside the map mapped with its sMap[s[i]] = sMap.get(s[i], 0) + 1
integers 0 to 9. Write occurrence as its key. After iteration for i in range(len(s)):
a function that will return -1 Is the element is not present. if(sMap[s[i]] == 1):
return i
take this string as
return -1
Input and return the
index of the first
character that is non-
repeating.
D STRI Palin You are given a Valid Create a temporary copy of the string class Solution:
A NG drom string. Write a Palindrome with only alphanumeric characters. def isPalindrome(self, s: str) -> bool:
Y6 e function to check - LeetCode Start two pointers from left and right temp = ""
whether the string is most ends. Check If the character at for char in s:
a palindrome or not. both the indices are same, If not if char.isalnum():
return false. Else Update left and right. temp+=char.lower()
If the Iteration completes, return True start = 0
end = len(temp) - 1
while(start <= end):
if(temp[start]!=temp[end]):
return False
start += 1
end -= 1
return True
D STRI Long Given a string s, find Longest Maintain a hashmap to keep track of class Solution:
A NG est the length of the Substringrepeating character of the string by def lengthOfLongestSubstring(self, s: str) -> int:
Y7 Uniq longest substring Without storing the character as the key and its map = {}
ue without repeating Repeatinglatest index as the value. maxLen = 0
char characters. Characters
Let the length be 0 and start from the start = 0
Subst - LeetCode
first character of the string. for i in range(len(s)):
ring Iterate over each character of the char = s[i]
if(char in map):
entire string, Check If the character is
start = max(start, map[char] + 1)
seen before, If yes, Move the start to
maxLen = max(maxLen, i - start + 1)
max(start, previous occurrence of that map[char] = i
character). Update the result by taking return maxLen
out the max(current result, current
index - start + 1). Put the character in
the map with its current index. At last,
return result. T,S => O(N)
D STRI Grou Given an array of Group Anagram string if sorted will the same. class Solution:
A NG p strings consisting of Anagrams - car => acr and arc => acr def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
Y7 Anagr lower case English LeetCode Iterate over each string of the array. map = {}
ams letters, group the Sort the current string. If the sorted for str in strs:
anagrams together. version of current string is in the word = ''.join(sorted(str))
You can return the hasmap, push the current string as the if word not in map:
answer in any order. value by having the sorted version as map[word] = [str]
else:
An Anagram is a the key. If Not, Make the sorted
map[word].append(str)
word or phrase version of the string as the key and
return map.values()
formed by have the value in the form of array by
rearranging the adding the current string
letters of a different T => O(N * klogk) => N -> length of the
word or phrase, array, k -> length of the string
using all the original S => O(N * k) => N -> length of the
letters exactly once. array, k -> length of the string
D SEA Binar Given an array of Binary Start from left and right. Find middle, If class Solution:
A RCHI y integers which is Search - middle is grater than target, move def search(self, nums: List[int], target: int) -> int:
Y8 NG Searc sorted in ascending LeetCode right to middle and compute again. If left = 0
h order, and a target middle is less than the target, move right = len(nums)-1
integer, write a left to middle. Iterate this until we find while(left<=right):
function to search the element. T => O(logN) -> Since we mid = (left + right)//2
for whether the are neglecting half of the element in if nums[mid] == target:
return mid
target integer is each iteration. Space => O(1).
elif nums[mid] < target:
there in the given
left+=1
array. If it is there else:
then return its index. right-=1
Otherwise, return -1. return -1
You must write an
algorithm with O(log
n) runtime
complexity.
D SEA Searc You are given an Search in Start from left and right. Find middle, If class Solution(object):
A RCHI h in integer array nums Rotated middle is equal to target return def search(self, nums, target):
Y8 NG Rotat sorted in ascending Sorted middle. Else Find the sorted part. In a left = 0
ed order (with distinct Array - sorted rotated array, Any of the left or right = len(nums) - 1
Sorte values). Prior to LeetCode right part will be sorted. Find the while(left <= right):
d being passed to your sorted path by checking array[left] mid = (left+right)//2
array function, nums is with array[mid]. If Left is sorted, check if(nums[mid] == target):
return mid
possibly rotated at if the target lies between left and mid.
if(nums[left] <= nums[mid]):
an unknown pivot If Yes, move right to mid - 1. If Not,
if(target >= nums[left] and target < nums[mid]):
index k (1 <= k < move right to mid +1. Else if Right is right = mid - 1
nums.length) such sorted, If the target lies between mid else:
that the resulting and right, move left to mid +1 else left = mid + 1
array is [nums[k], move right to mid - 1. Return -1 after else:
nums[k+1], ..., nums Iteration if(target > nums[mid] and target <= nums[right]):
[n-1], nums[0], nums left = mid + 1
[1], ..., nums[k-1]] (0- else:
indexed). right = mid - 1
For example, return -1
[0,1,2,4,5,6,7] might
be rotated at pivot
index 3 and become
[4,5,6,7,0,1,2]. Given
an integer target,
return the index of
target if it is in the
array, else return -1.
You must write an
algorithm with O(log
n) runtime
complexity.
D SEA Find You are given an Find First Need Two Binary Search One to find class Solution(object):
A RCHI First array of integers and Last the leftmost occurrence and another def searchRange(self, nums, target):
Y9 NG and sorted in non- Position of to find the rightmost occurrence. For range = [-1, -1]
Last decreasing order, Element in Finding leftmost occurrence, Even if left = 0
Positi find the starting and Sorted the target is at the middle, make right = len(nums) - 1
on of ending position of a Array - leftmost occurrence as middle and while left <= right:
Elem given target value. If LeetCode update the right = mid-1 and For right mid = (left+right) // 2
if target < nums[mid]:
ent in target is not found in case, make rightmost occurrence as
right = mid - 1
Sorte the array, return [-1, middle and update left = mid+1
elif target > nums[mid]:
d -1]. You must write left = mid + 1
Array an algorithm with O else:
(log n) runtime range[0] = mid
complexity. right = mid - 1
left = 0
right = len(nums) - 1
while left <= right:
mid = (left+right) // 2
if target < nums[mid]:
right = mid - 1
elif target > nums[mid]:
left = mid + 1
else:
range[1] = mid
left = mid + 1
return range
D SEA Searc Write an efficient Search a Start From the Top Right cell, If the class Solution(object):
A RCHI h in algorithm that 2D Matrix - target is less than It, decrease the def searchMatrix(self, matrix, target):
Y9 NG 2D searches for a value LeetCode column to search and if greater, rows = len(matrix)
Array target in an m x n increase the row to search. Search cols = len(matrix[0])
integer matrix. This Unless row < Number Of Rows and Col row = 0
matrix has the >= 0 col = cols - 1
following properties: while row < rows and col >= 0:
if matrix[row][col] == target:
Integers in each row
return True
are sorted from left
elif matrix[row][col] < target:
to right. row += 1
The first integer of else:
each row is greater col -= 1
than the last integer return False
of the previous row.
If the value is there
in the matrix return
true, else false.
D SOR Bubbl You are given an Bubble Sort Run a nested for loop to traverse the class Solution(object):
A TIN e Sort array of integers. | Practice | input array using two variables i and j, def sortColors(self, nums):
Y1 G Write a function that GeeksforG such that 0 ≤ i < n-1 and 0 ≤ j < n-i-1 for i in range(len(nums)):
0 will take this array as eeks If arr[j] is greater than arr[j+1] then for j in range(len(nums)-i-1):
input and return the swap these adjacent elements, else if(nums[j] > nums[j+1]):
sorted array using nums[j+1], nums[j] = nums[j],nums[j+1]
move on. O(N^2) Time Solution
Bubble sort.
D SOR Insert You are given an Insertion The Idea of the algorithm is to consider class Solution:
A TIN ion array of integers. Sort | left part as sorted and the right part as def sortColors(self, nums: List[int]) -> None:
Y1 G Sort Write a function that Practice |unsorted. And Take the first element # Insertion Sort
0 will take this array as GeeksforG from the unsorted part and inset that for i in range(1, len(nums)):
input and return the eeks into the sorted part. Iterate over the temp = nums[i]
sorted array using array from the element at the index 1 j=i-1
Insertion sort. as i and consider the elements at the while j >=0 and nums[j] > temp:
nums[j+1] = nums[j]
index i-1 as sorted where j=i-1, store
j -= 1
the array[i] into a temp variable. While
nums[j+1] = temp
j>=0 and the array[j]>temp, overwrite
array[j] with array[j+1] i.e., array[j+1] =
array[j]. and decrement j. By this we
can make a space to insert the temp at
its correct position at array[j+1] =
temp. This is a stable sorting algo with
O(N^2) => Worst and Avg Time and O
(N) Best time with O(1) Space.
D SOR Selec You are given an Selection The idea is to find the smallest class Solution:
A TIN tion array of integers. Sort | element from i to n-1 and put it into def selectionSort(self, arr,n):
Y1 G Sort Write a function that Practice | the first index by swapping the first #code here
1 will take this array as GeeksforG element with the smallest element. for i in range(n-1):
input and return the eeks And second element with the second current = i
sorted array using smallest and so on. In the second for j in range(i+1, n):
Selection sort. iteration, current will give the smallest if arr[j] < arr[current]:
current = j
element in the range i+1 to n. Select
arr[current], arr[i] = arr[i], arr[current]
smallest and put it. Hence the name
selection sort. O(N^2) time and O(1)
space.
D SOR Merg You are given an Sort an The idea behind this algorithm is to class Solution(object):
A TIN e Sort array of integers. Array - divide the entire array into single def mergeSortedArrays(self, left, right):
Y1 G Write a function that LeetCode elemented sub array and to merge result = []
1 will take this array as each of the arrays in sorted order. This i=0
input and return the way a binary tree like structure is j=0
sorted array using formed. Split the entire array in the while i < len(left) and j < len(right):
Merge sort. mid and save them as left and right if left[i] <= right[j]:
result.append(left[i])
and recursively call left and right for
i += 1
spliiting. This way the entire array will
else:
get splitted into single element and result.append(right[j])
merge the splitted array by comparing j += 1
left[i] and right[j] and appending the while i < len(left):
smaller element into the result. result.append(left[i])
i += 1
while j < len(right):
result.append(right[j])
j += 1
return result
def sortArray(self, nums):
if len(nums) <= 1:
return nums
mid = len(nums) // 2
left = self.sortArray(nums[:mid])
right = self.sortArray(nums[mid:])
return self.mergeSortedArrays(left, right)
D SOR Quick You are given an Quick Sort The idea is to select an element and to class Solution:
A TIN Sort array of integers. | Practice | place that in its right position, So that #Function to sort a list using quick sort algorithm.
Y1 G Write a function that GeeksforG every element of its left if lesser than def quickSort(self,arr,low,high):
2 will take this array as eeks that and right is greater than that. We if low < high:
input and return the need a partition algorithm to place the pivIdx = self.partition(arr,low, high)
sorted array using pivot element at its right position and self.quickSort(arr,low,pivIdx-1)
Quick sort. to return the index of the pivot. Then self.quickSort(arr,pivIdx+1, high)
Recursively call the quick sort on both return arr
the left and right partitions of the
def partition(self,arr,low,high):
array. The Avg Time is O(NLogN) and
mid = (low+high) // 2
worst case is O(N^2). Worst case
arr[low], arr[mid] = arr[mid], arr[low]
happens when the arrray is sorted. To
pivot = arr[low]
avoid that, we need to get the middle
start = low + 1
element and place that at the starting end = high
position to shuffle the array. while start <= end:
if arr[start] <= pivot:
start += 1
if arr[end] > pivot:
end -= 1
if start < end:
arr[start], arr[end] = arr[end], arr[start]
arr[low], arr[end] = arr[end], arr[low]
return end

D SOR Radix You are given an


A TIN Sort array of non-negative
Y1 G integers. Write a
2 function that will
take this array as
input and return the
sorted array using
Radix sort.
D SING Const Design a Singly linked Design Initialize the ListNode with a value and class ListNode:
A LY ruct list class that has a Linked List its next pointing to Null. def __init__(self, val):
Y1 LINK SLL head and tail. Every - LeetCode Initialize a Linked List with head as self.val = val
3 ED node is to have two None and Size as 0. self.next = None
LIST attributes: value: the Edge Case: When the Given Index < 0
value of the current or Index > size. class MyLinkedList(object):
node, and next: a
def __init__(self):
pointer to the next Get val and Index
self.head = None
node. The linked list Check Edge Cases. Else, Have head as
self.size = 0
is to be 0-indexed. current and move current to its next
The class should until it reaches index with forLoop. def get(self, index):
support the After Iteration, return crrent.val if index < 0 or index >= self.size:
following: T -> O(Index) return -1
SinglyLinkedList() curr = self.head
Initializes the Add at Index for i in range(0,index):
SinglyLinkedList if Index > size: return curr = curr.next
object. have curr as head. create a new node return curr.val
get(index) Get the with the given value.
value of the indexth If Index <=0 meand, Add at Head => def addAtHead(self, val):
node. If the index is new node's next is head. updated self.addAtIndex(0, val)
invalid, return -1. head is now new node
addAtHead(value)- else : Iterate until curr reaches index-1. def addAtTail(self, val):
Add a node of given new node's next = curr.next, curr.next self.addAtIndex(self.size, val)
value before the first = new node
element of the linked Increase size of the Linked List
def addAtIndex(self, index, val):
list. To add at head, send index as 0 to add if(index > self.size):
addAtTail(value) - at index and index as size for adding at return
Add a node of given tail curr = self.head
value at the last T -> O(Index) temp = ListNode(val)
element of the linked if index <= 0:
list. Delete at Index temp.next = self.head
addAtIndex(index, Check Edge case, have current as self.head = temp
value) Add a node of head. else:
given value before If index is 0, delete head by self.head = for i in range(0, index-1):
the indexth node in self.head.next curr = curr.next
the linked list. If Else: Iterate until curr reaches index-1. prev = curr.next
index equals the curr.next = curr.next.next curr.next = temp
length of the linked Decrease size of the Linked List temp.next = prev
list, the node will be T -> O(Index) self.size += 1
appended to the end
of the linked list. If
def deleteAtIndex(self, index):
index is greater than
if(index < 0 or index >= self.size):
the length, don’t return
insert the node. curr = self.head
deleteAtIndex(index) if index == 0:
Delete the indexth self.head = self.head.next
node in the linked else:
list, if the index is for i in range(0, index-1):
valid, else nothing curr = curr.next
happens. curr.next = curr.next.next
self.size -= 1
D SING delet You are given the Remove The Idea is to find the next distinct class Solution(object):
A LY e head of a Sorted Duplicates element and make it as next to the def deleteDuplicates(self, head):
Y1 LINK dupliSingly Linked list. from current element. if head is None:
3 ED cates Write a function that Sorted List Edge Case : If head is Node: Return return head
LIST will take the given - LeetCode None curr = head
head as input, delete Have current and next distinct node = curr.next
all nodes that have a variables at node 1 and 2. Iterate until while node:
if curr.val != node.val:
value that is already next distinct reaches None.if the
curr = curr.next
the value of another values of both are distinve, move both
node = node.next
node so that each by one position. Else, Move next else:
value appears 1 time distince by one position and make node = node.next
only and return the current.next = next distinct. curr.next = node
linked list, which is return head
still to be a sorted
linked list.
D SING Rever You are given the Reverse We Need prev = Null and take current class Solution(object):
A LY se SLL head of a Singly Linked List as head. def reverseList(self, head):
Y1 LINK Linked list. Write a - LeetCode Iterate until current is not null, take a prev = None
4 ED function that will temporary element having curr.next curr = head
LIST take the given head since we are removing the connection
as input, reverse the between current and its next. while curr:
Linked List and Now point curr.next to prev and move next = curr.next
curr.next = prev
return the new head prev and curr one step ahead. i.e.,
prev = curr
of the reversed prev = curr and curr = next
curr = next
Linked List. return prev
D SING Cycle You are given the Linked List Brute Force : Maintain a hashmap to class Solution(object):
A LY Detec head of a linked list. Cycle II - store visited nodes. If the a node def detectCycle(self, head):
Y1 LINK tion Check if there is a LeetCode points to a visited node, the cycle if not head or not head.next:
4 ED cycle and if yes, exists. return None
LIST return the node T => O(N) , S => O(N) slow = head
where the cycle Optimized : Floyyd Tortoise and Hare's fast = head
begins. If there is no Algorithm. Maintain a slow and fast while fast and fast.next:
slow = slow.next
cycle, return null. pointer. Slow moves one at a time and
fast = fast.next.next
There is a cycle in a fast moves two nodes at a time.
if slow == fast:
linked list if there is If slow meets fast, Cycle Exists. break
some node in the list To detect the the node at which the if slow!=fast:
that can be reached cycle starts, move slow to head. and return None
again by now move slow and fast one at a time. slow = head
continuously It will collide at a node and return that while slow != fast:
following the next node. slow = slow.next
pointer. Do not T => O(N) => Since slow will run only fast = fast.next
modify the linked list. one cycle , S => O(1) return slow
D SING find Given an array of Find the Same as that of the above algo. Floyyd class Solution:
A LY dupli integers nums Duplicate Tortoise and Hare Algorithm. def findDuplicate(self, nums: List[int]) -> int:
Y1 LINK cate containing n + 1 Number - slow = 0
5 ED numb integers where each LeetCode fast = 0
LIST er integer is in the while True:
range [1, n] inclusive. slow = nums[slow]
There is only one fast = nums[nums[fast]]
if slow == fast:
repeated number in
break
nums, return this
slow = 0
repeated number. while slow != fast:
You must solve the slow = nums[slow]
problem without fast = nums[fast]
modifying the array return slow
nums and uses only
constant extra space.
D SING Add 2 You are given two Add Two Let the carryForwrad be 0. Create a class Solution:
A LY numb non-empty linked Numbers - node pointer of 0 and make result def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
Y1 LINK ers lists representing LeetCode equal to that pointer. carryFwd = 0
5 ED two non-negative while l1 or l2 or carryFwd, take l1.val pointer = ListNode(0)
LIST integers. The digits and l2.val if present else 0. Let the sum result = pointer
are stored in reverse at this digits place be
order, and each of sum = l1val + l2val + carryFwd. Take while l1 or l2 or carryFwd:
l1Val = l1.val if l1 else 0
their nodes contains the one's place of sum as num by num
l2Val = l2.val if l2 else 0
a single digit. Add the = sum %10. and take the carryFwd by
two numbers and diving the sum by 10 and taking the sum = l1Val + l2Val + carryFwd
return the sum as a reminder. num = sum % 10
linked list. Create a new node with num and carryFwd = sum // 10
You may assume the make it as the next of the pointer node
two numbers do not and move pointer ahead. pointer.next = ListNode(num)
contain any leading If l1.next, move l1 and l2.next, move pointer = pointer.next
zero, except the l2.
number 0 itself. Return result.next => which will be the l1 = l1.next if l1 else None
0<=Node value<=9 actual head of the list l2 = l2.next if l2 else None

return result.next
D DOU DLL Create a Doubly https: Construct a Node with a Node class Construct DLL Class
A BLY remo Linked List class. //replit. and a DLL with DLL class 1. Remove
Y1 LINK ve Write Instance com/@001 1. Remove def remove(self, node):
6 ED insert Methods for this AakashAak If the node to be removed is head, if self.head == node:
LIST class to be able to ash/Python point head to head.next self.head = self.head.next
1.remove a node #doublyLin If the node to be removed is tail, point if self.tail == node:
when the node to be kedList.py tail to tail.prev self.tail = self.tail.prev
removed is given as If the node to be removed has a prev
if node.prev:
Input. node, point node.prev.next. = node.
node.prev.next = node.next
2. insert a node next
before a particular If the node to be removed has a next if node.next:
node(both the node node, point node.next.prev = node. node.next.prev = node.prev
to be inserted and prev
the node before 2. Insert
which the insertion is 2. Insert def insert(self, node, new_node):
to happen will be If the list has only one node and that is if self.head == new_node and self.tail == new_node:
given as input). If the the node to be inserted, Just return return
node to be inserted We have two case, (i) - If the new node self.remove(new_node)
is is already present and (ii) not present. new_node.prev = node.prev
-part of the linked list To merge these cases, just remove the new_node.next = node
then shift its place to new node from the list if node == self.head:
the desired location Now point new_node.prev to node. self.head = new_node
-a new node, then prev and new_node.next = node else:
node.prev.next = new_node
insert the new node If the given node is head, make head
node.prev = new_node
at the place desired. as new_node
Else point node.prev.next = new_node
node.prev = new_node
D DOU DLL Create a Doubly https: 1. Remove All 1. Remove All
A BLY remo Linked List class. //www. Have current as head. def removeAll(self, val):
Y1 LINK ve all, Write Instance onlinegdb. Traverse over the list, make temp = curr = self.head #1 2 3 4 5
6 ED insert Methods for this com/edit/8 curr and curr = curr.next. Its important while curr:
LIST at class to be able to IVK9AYbI to have a copy of curr as temp. temp = curr
positi 1. remove all the If temp.data == val, remove temp curr = curr.next
on nodes in the doubly if temp.data == val:
self.remove(temp)
linked list which have 2. Insert at given Position
their value equal to a Have curr as head and count as 0.
2. Insert at given Position
given value. Traverse over the list until curr exists def insertPos(self, pos, new_node):
2.Insert a node at a and position is not eqaul to count. curr = self.head
desired position If position is equal to count, we surely count = 0
(node and position have a node, in which the new_node while curr and pos != count:
are given). The has to be inserted before. count += 1
Linked List is 0 move curr and increment count. curr = curr.next
indexed. If given If curr is present: insert new_node at if curr:
node is a node curr with the insert function. self.insert(curr, new_node)
existing in the Linked If not we have 2 case, else:
List shift it to the (i) -> If head is not present, point if not self.head:
desired position. head and tail to new_node self.head = new_node
(ii) -> Else: remove new_node from self.tail = new_node
list, point next of new_node to null, else:
new_node.prev = tail and self.remove(new_node)
new_node.next = None
tail.next = new_node and make tail as
new_node.prev = self.tail
new_node
self.tail.next = new_node
self.tail = new_node
D STA Const Implement a Stack: https: Create a Linked List Node class Node:
A CKS ruct Using an Array //www. Create a stack class. def __init__(self, data):
Y1 Stack with a Stack class onlinegdb. Initiaize its first and last to None and self.data = data
7 using a Linked list com/edit/a make its size as 0. self.next = None
One should be able zqnaMHYh
to add to the stack Add at Top class Stack:
and remove from the If the stack is empty, Create a Node of def __init__(self):
self.first = None
stack following the te given val and make it as first and
self.last = None
LIFO property. last.
self.size = 0
Else: Store first. Make First as new
Node. Make next of new Node to def addAtTop(self, val):
temp. if not self.first:
Increment Size self.first = Node(val)
self.last = self.first
Remove From Top else:
If first is not present Return. temp = self.first
Then make first = first.next. self.first = Node(val)
Decrement Size. If Size becomes 0, self.first.next = temp
then make last as None self.size += 1
Return self.first return self

def removeFromTop(self):
if not self.first:
return None
temp = self.first
self.first = self.first.next
self.size -= 1
if self.size == 0:
self.last = None
return temp

def __str__(self):
current = self.first
elements = []
while current:
elements.append(str(current.data))
current = current.next
return "Stack: " + ", ".join(elements)

st = Stack()
st.addAtTop(5)
st.addAtTop(75)
st.addAtTop(35)
st.addAtTop(15)
st.removeFromTop()

print(st)
D STA Rever Evaluate the value of Evaluate class Solution:
A CKS se an arithmetic Reverse def evalRPN(self, tokens: List[str]) -> int:
Y1 Polish expression in Polish stack = []
7 Notat Reverse Polish Notation - for i in tokens:
ion Notation(See LeetCode if i == '/' or i == '+' or i == '-' or i == '*':
example). Valid num2 = stack.pop()
operators are +, -, *, num1 = stack.pop()
if i == '+':
and /. Note that
res = num1 + num2
division between two
elif i == '-':
integers should res = num1 - num2
truncate toward elif i == '*':
zero. It is guaranteed res = num1 * num2
that the given RPN else:
expression is always res = int(num1 / num2)
valid. That means the stack.append(res)
expression would else:
always evaluate to a stack.append(int(i))
result, and there will return stack.pop()
not be any division
by zero operation.
The Input is an array
of strings where each
element is either a
valid operator or an
integer. E.g.[“1”,”2”,”
+”]
D QUE Const Implement a Queue: https: class Node:
A UES ruct Using an Array //www. def __init__(self, data):
Y1 Queu with a Queue class onlinegdb. self.next = None
8 e using a Linked list com/edit/a self.data = data
One should be able XlwspLf_
to add to the queue class Queue:
and remove from the def __init__(self):
self.first = None
queue following the
self.last = None
FIFO property.
self.size = 0

def enqueue(self, val):


node = Node(val)
if self.first == None:
self.first = node
self.last = node
else:
self.last.next = node
self.last = node
self.size += 1
return self

def dequeue(self):
if self.first == None:
return None
first = self.first
self.first = first.next
self.size -= 1
if self.size == 0:
self.last = None
return first

def __str__(self):
values = []
current = self.first
while current:
values.append(str(current.data))
current = current.next
return 'Queue: ' + ', '.join(values)

queue = Queue();
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue)
queue.dequeue()
print(queue)
queue.dequeue()
print(queue)
queue.dequeue()
print(queue)
queue.dequeue()
print(queue)
D QUE Imple Implement a first in Implement class MyQueue:
A UES ment first out (FIFO) queue Queue
Y1 Queu using only two using def __init__(self):
8 e stacks. The Stacks - self.inStack = []
with implemented queue LeetCode self.outStack = []
Stack should support all
the functions of a def push(self, x: int) -> None:
self.inStack.append(x)
normal queue (push,
peek, pop, and
def pop(self) -> int:
empty). if len(self.outStack) == 0:
Implement the while len(self.inStack) > 0:
MyQueue class: self.outStack.append(self.inStack.pop())
push(val) Pushes return self.outStack.pop()
element val to the
back of the queue. def peek(self) -> int:
pop() Removes the if len(self.outStack) == 0:
element from the while len(self.inStack) > 0:
front of the queue self.outStack.append(self.inStack.pop())
and returns it. return self.outStack[-1]
peek() Returns the
element at the front def empty(self) -> bool:
of the queue. if len(self.outStack) == 0 and len(self.inStack) == 0:
empty() Returns true return True
return False
if the queue is
empty, false
otherwise.

Notes:
You must use only
standard operations
of a stack, which
means only push to
top, peek/pop from
top, size, and is
empty operations are
valid.
Depending on your
language, the stack
may not be
supported natively.
You may simulate a
stack using a list or
deque (double-
ended queue) as long
as you use only a
stack's standard
operations.

Follow-up:
Implement the
queue such that each
operation is
amortized O(1) time
complexity. In other
words, performing n
operations will take
overall O(n) time
even if one of those
operations may take
D BIN Const Design a Binary Insert Insert: Insert
A ARY ruct Search Tree class Insert into If Tree does not exists, Create a new def insertIntoBST(self, root, val):
Y1 TRE BST that supports the a Binary Node and return it as Tree if not root:
9 E following: Search Else: If the given val is greater than the return TreeNode(val)
AND 1.Insert a value Tree - root.val means We need to put val to if val > root.val:
BST 2.Remove a value. LeetCode root.right and vice versa. root.right = self.insertIntoBST(root.right, val)
This method should Return root at last. elif val < root.val:
root.left = self.insertIntoBST(root.left, val)
remove the first Delete
return root
occurrence of a Delete Delete
value. Node in a if not root, return Null Delete
3.Find a value. If the BST - If the given val is greater than the root. def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
value is found it LeetCode val means We need to search for val in if not root:
should return the root.right and vice versa. return None
node with the value Find Else: Now we have reached our if key > root.val:
else return false. Search in a destination node. root.right = self.deleteNode(root.right, key)
Binary Here exists two cases. elif key < root.val:
Search (i) -> If the node has 0 or 1 children, root.left = self.deleteNode(root.left, key)
Tree - We can directly set the node to null else:
LeetCode that node if it has 0 children. If it has 1 if not root.left:
children, set the not null right or left return root.right
Node. elif not root.right:
(ii) -> If It has 2 children, get the return root.left
minimum value node of the current. else:
minNode = self.getMinNode(root.right)
right subtree. Replace the root value
root.val = minNode.val
with minimum value. Now two
root.right = self.deleteNode(root.right, minNode.val)
minimum nodes will be there. To return root
delete the child, Recursively call root.
right with minimum value def getMinNode(self, root):
curr = root
Find while(curr and curr.left):
if not root, return Null curr = curr.left
If the given val is greater than the root. return curr
val means We need to search for val in
root.right and vice versa. Find
If found return root def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root:
return None
if val > root.val:
return self.searchBST(root.right, val)
elif val < root.val:
return self.searchBST(root.left, val)
else:
return root
D BIN Trave Write a 4 instance BFS : Level BFS : Level Order BFS : Level Order
A ARY rse methods for a Binary Order Create a Queue and push root. create def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
Y1 TRE BST Search Tree class to https: res= []. Iterate till the range of queue. if root is None:
9 E traverse the BST. //leetcode. Create an arr = []. Push the curr = return []
AND 1. Method 1 : com/probl queue.pop(0) element's val into the res = []
BST traverse the tree ems/binary array. queue = []
breadth first and -tree-level- Append curr.left and right into the queue.append(root)
while len(queue) > 0:
return an array that order- queue. And append arr into res to
arr = []
contains all the traversal form 2D array.
for _ in range(len(queue)):
values of the BST. curr = queue.pop(0)
2. Method 2: DFS: DFS: Inorder: arr.append(curr.val)
traverse the tree Inorder Call left Push curr.val and call right if curr.left:
depth first – In-order https: queue.append(curr.left)
and return an array //leetcode. DFS: Preorder: if curr.right:
that contains all the com/probl Push curr.val, call left and call right queue.append(curr.right)
values of the BST. ems/binary res.append(arr)
3. Method 3 : -tree- DFS: Postorder: return res
traverse the tree inorder- Call left, call right and push curr.val
depth first – Pre- traversal/ DFS : Inorder
order and return an def inorder_helper(self, node, res):
array that contains DFS: if node.left:
all the values of the Preorder: self.inorder_helper(node.left, res)
BST. https: res.append(node.val)
if node.right:
4. Method 4 : //leetcode.
self.inorder_helper(node.right, res)
traverse the tree com/probl
depth first – Post- ems/binary def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
order and return an -tree- if not root: return []
array that contains preorder- res = []
all the values of the traversal/ self.inorder_helper(root, res)
BST. return res
DFS:
Postorder: DFS: Preorder:
https: def preorderTraversal_helper(self, node, res):
//leetcode. if not node:
com/probl return
ems/binary res.append(node.val)
-tree- self.preorderTraversal_helper(node.left, res)
postorder- self.preorderTraversal_helper(node.right, res)
traversal/ def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root: return []
res = []
self.preorderTraversal_helper(root,res)
return res

DFS: Postorder:
def postorderTraversal_helper(self, node, res):
if not node:
return
self.postorderTraversal_helper(node.left, res)
self.postorderTraversal_helper(node.right, res)
res.append(node.val)
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root: return []
res = []
self.postorderTraversal_helper(root,res)
return res
D BIN Level Write a function that BFS : Level BFS : Level Order def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
A ARY Order takes the root of a Order Create a Queue and push root. create res= []. if root is None:
Y2 TRE trave binary tree, and https: Iterate till the range of queue. Create an arr = [].return []
0 E rsal returns the level //leetcode. Push the curr = queue.pop(0) element's val into resthe= []array.
AND order traversal of its com/probl Append curr.left and right into the queue. Andqueue append = []
arr into res to form 2D array.
BST nodes' values. (i.e., ems/binary queue.append(root)
from left to right, -tree-level- while len(queue) > 0:
arr = []
level by level). order-
for _ in range(len(queue)):
Initially write an traversal/
curr = queue.pop(0)
instance method for arr.append(curr.val)
the Binary Search if curr.left:
tree class to insert queue.append(curr.left)
the values given as if curr.right:
an array into the queue.append(curr.right)
Binary tree (from left res.append(arr)
to right, level by return res
level). Each value in
the array which is
not null is to be
made a node and
added to the tree.
(See examples
below). Then write
the function
mentioned first.
D BIN Left/ 1. Given the root of a https: Same as that of the BFS. But at each def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
A ARY Right binary tree, imagine //leetcode. level push the first element(left sie) or if not root: return []
Y2 TRE View yourself standing on com/probl the last element(right side) res = []
0 E of the right side of it, ems/binary queue = []
AND binar return the values of -tree-right- queue.append(root)
BST y tree the nodes you can side- while queue:
see ordered from top view/submi count = len(queue)
for _ in range(count):
to bottom. ssions/
curr = queue.pop(0)
2. Given the root of a
if(_ == count-1):
binary tree, imagine res.append(curr.val)
yourself standing on if curr.left:
the left side of it, queue.append(curr.left)
return the values of if curr.right:
the nodes you can queue.append(curr.right)
see ordered from top return res
to bottom.
D BIN Invert Given the root of a Invert Recursive: Recursive Iterative
A ARY Binar binary tree, invert Binary Tree swap root.left with root.right and def invertTree(self, root: Optional[TreeNode])
def invertTree(self, -> Optional[TreeNode]:
root):
Y2 TRE y the tree, and return - LeetCode recurivley call the function with root. if not root: if not root:
1 E Tree its root. left and right return None return root
AND (Invert means swap queue = [root]
BST every left node for its Iterative: temp = root.left while queue:
corresponding right Like BFS. Instead of adding elements to root.left = root.right curr = queue.pop(0)
root.right = temp curr.left, curr.right = curr.right, curr.left
node / get mirror the array at each level, Swap left with
if curr.left:
image) right
self.invertTree(root.left) queue.append(curr.left)
self.invertTree(root.right) if curr.right:
queue.append(curr.right)
return root return root
D BIN Diam Write a function Diameter Diameter = depth(right) subtree + def depth(self, node):
A ARY eter which takes in the of Binary depth(left) subtree + 1 if not node:
Y2 TRE of root of a binary tree Tree - So we need to find depth of the root. return 0
1 E binar and returns the LeetCode Need a instance variable for result. left = self.depth(node.left)
AND y tree length of the Call depth method with root right = self.depth(node.right)
BST diameter of the tree. If root is none, return 0(edge case) => self.res = max(left+right, self.res)
The diameter of a For leaf nodes, The depth will be 0. return max(left, right) + 1
def diameterOfBinaryTree(self, root):
binary tree is the Recursively move to left and right
self.res = 0
length of the longest nodes.
self.depth(root)
path between any Update res = max(left+right, res) => return self.res
two nodes in the Res = diameter(sum of depth of left
tree. It is not and right)
necessary for this Return max height of left and right +1
path to pass through => max(left, right) +1
the root of the tree.
The length of a path
between two nodes
is the number of
edges between
them.
D BIN Conv You are given an Convert To construct a height balanced Binary def sortedArrayToBST(self, nums):
A ARY ert array where the Sorted Tree, We Need to take the middle if len(nums) == 0:
Y2 TRE Sorte elements are strictly Array to element as root. return None
2 E d in increasing Binary Base Case : If not root: Return None mid = len(nums) // 2
AND Array (ascending) order, Search Create a Treenode with middle root = TreeNode(nums[mid])
BST to convert it to a Tree - element (For first call, It will be the root.left = self.sortedArrayToBST(nums[:mid])
Binar height-balanced LeetCode root). root.right = self.sortedArrayToBST(nums[mid+1:])
return root
y binary search tree. A Recursively call the function with left
Searc height-balanced side and right side of the array and
h binary tree is a assign it ro root.left and right
Tree binary tree in which respectively.
the depth of the two
subtrees of every
node does not differ
by more than 1.
D BIN Valid You are given the Validate We Need to call the function def helper(self,root,low, high):
A ARY ate root of a binary tree, Binary recursively with thr root and least(-inf) if not root:
Y2 TRE BST determine if it is a Search => low and most(inf) value => high. return True
2 E valid binary search Tree - Edge Case: If not root: return True if not (low < root.val < high):
AND tree (BST). A valid LeetCode If low < root.val < high: return False return False
BST BST is defined as Else Recurively cal and return left and return self.helper(root.left, low, root.val) and self.helper(root.right, root.val, high)
follows: right side of the tree
def isValidBST(self, root):
The left subtree of a
return self.helper(root,float('-inf'), float('inf'))
node contains only
nodes with keys less
than the node's key.
The right subtree of a
node contains only
nodes with keys
greater than the
node's key.
Both the left and
right subtrees must
also be binary search
trees.
D HEA Max Write a max Heap class BinaryHeap:
A PS Heap Class that supports def __init__(self):
Y2 AND Const the following: self.heap = []
3 PRIO ructio 1.Building a Max self.length = 0
RITY n heap from an input
QUE array def buildHeap(self, array):
UE 2.Inserting integers self.heap = array
self.length = len(array)
in the Heap
lastParentIdx = (self.length // 2) - 1
3.Removing the
for i in range(lastParentIdx, -1, -1):
Heap’s maximum / self.bubbleDown(i)
root value return self.heap
4.Peeking at the
Heap’s maximum / def bubbleDown(self, idx):
root value array = self.heap
The Heap is to be current = array[idx]
represented in the leftChildIdx = (2 * idx) + 1
form of an array. rightChildIdx = (2 * idx) + 2
largestEleIdx = idx

if leftChildIdx < self.length and array[leftChildIdx] > array[largestEleIdx]:


largestEleIdx = leftChildIdx

if rightChildIdx < self.length and array[rightChildIdx] > array[largestEleIdx]:


largestEleIdx = rightChildIdx

if largestEleIdx != idx:
array[idx], array[largestEleIdx] = array[largestEleIdx], array[idx]
self.bubbleDown(largestEleIdx)

def getMax(self):
maxVal = self.heap[0]
last = self.heap.pop()
self.length -= 1
if len(self.heap) > 0:
self.heap[0] = last
self.bubbleDown(0)
return maxVal

def bubbleUp(self, idx):


array = self.heap
current = array[idx]
parentIdx = (idx - 1) // 2
while idx > 0 and current > array[parentIdx]:
array[idx] = array[parentIdx]
idx = parentIdx
parentIdx = (idx - 1) // 2
array[idx] = current

def insert(self, value):


self.heap.append(value)
self.length += 1
self.bubbleUp(self.length - 1)
return self.heap

def returnObj(self):
return self.heap

heap = BinaryHeap()
array = [4,5,6,2,3,7] => [13,5,7,2,3,4, 6]
print(heap.buildHeap(array))
D HEA min Implement a Priority class PriorityQueue:
A PS Priori Queue as a min def __init__(self):
Y2 AND ty Binary Heap. The self.heap = []
3 PRIO Queu Priority Queue class self.length = 0
RITY e should support the
QUE Const following functions def buildHeap(self, nodes):
UE ructio 1.Enqueue to insert self.heap = nodes
self.length = len(nodes)
n an element
lastParentIdx = (self.length // 2) - 1
2.Dequeue to extract
for i in range(lastParentIdx, -1, -1):
the element with the self.bubbleDown(i)
highest priority ( return self.heap
lowest numerical
priority is treated as def bubbleDown(self, idx):
highest priority) array = self.heap
current = array[idx]
leftChildIdx = (2 * idx) + 1
rightChildIdx = (2 * idx) + 2
smallestEleIdx = idx

if leftChildIdx < self.length and array[leftChildIdx].priority < array[smallestEleIdx].priority:


smallestEleIdx = leftChildIdx

if rightChildIdx < self.length and array[rightChildIdx].priority < array[smallestEleIdx].priority:


smallestEleIdx = rightChildIdx

if smallestEleIdx != idx:
array[idx], array[smallestEleIdx] = array[smallestEleIdx], array[idx]
self.bubbleDown(smallestEleIdx)

def enqueue(self, value, priority):


node = Node(value, priority)
self.heap.append(node)
self.length += 1
self.bubbleUp(self.length - 1)
return self

def bubbleUp(self, idx):


array = self.heap
current = array[idx]
parentIdx = (idx - 1) // 2
while idx > 0 and current.priority < array[parentIdx].priority:
array[idx] = array[parentIdx]
idx = parentIdx
parentIdx = (idx - 1) // 2
array[idx] = current

def dequeue(self):
minElement = self.heap[0]
last = self.heap.pop()
self.length -= 1
if len(self.heap) > 0:
self.heap[0] = last
self.bubbleDown(0)
return minElement

def returnObj(self):
return self.heap

priority_queue = PriorityQueue()

nodes = [Node('A', 4), Node('B', 2), Node('C', 6), Node('D', 1), Node('E', 3)]
D GRA BFS - You are given an Adjacencey List Adjacency List Implementation class Solution:
A PHS Adj undirected graph Time Complexity: adjacency_list = { #Function to return
y2 List stored Breadth-first search (BFS) has a time 'A': ['B', 'F'], Breadth First Traversal of
4 and as an adjacency list complexity of O(V + E), where V is the 'B': ['A', 'F', 'C'], given graph.
Adj as an adjacency number of vertices (or nodes) and E is 'C': ['B', 'E', 'D'], def bfsOfGraph(self, V: int,
Matri Matrix. the number of edges in the graph. This 'D': ['C', 'E'], adj: List[List[int]]) -> List[int]:
x Write functions to is because each node and each edge 'E': ['D', 'C', 'F'], # code here
'F': ['A', 'B', 'E'] res = []
traverse this graph will be explored once.
} queue = [0]
using the Breadth
visited = {}
first Search Space Complexity: def travBFS(graph, start): while(len(queue) > 0):
approach. As you The space complexity is O(V) because visited = {} # to keep track of visited current
nodes = queue.pop
traverse the graph in the worst-case scenario, all the queue = [start] # queue to process(0) nodes
store the values of vertices/nodes might end up in the output = [] # list to save the traversalres.append(current)
order
the vertices in an queue at the same time. visited[start] = True visited[current] = True
array and return this neighbours = adj
array. while len(queue) > 0: [current]
Adjacency Matrix current = queue.pop(0) for neighbour in
Time Complexity: output.append(current) neighbours:
if(neighbour not in
Breadth-first search (BFS) has a time neighbours = graph[current] visited):
complexity of O(V^2) when it is for neighbour in neighbours: queue.append
implemented with an adjacency if neighbour not in visited:
(neighbour)
matrix, where V is the number of queue.append(neighbour) visited
visited[neighbour] = True
[neighbour] = True
vertices (or nodes) in the graph. This is
because we need to traverse the
return output return res
entire row for each vertex to check for
its neighbours in the adjacency matrix. Adjacency Matrix Implementation
As there are V vertices and each row # Vertices and their indices
has V elements, this results in O(V^2) vertices = ['A', 'B', 'C', 'D', 'E', 'F']
time complexity. vertex_indices = { 'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5 }

Space Complexity: # The adjacency matrix


adjacency_matrix = [
The space complexity is O(V) because [0, 1, 0, 0, 0, 1],
in the worst-case scenario, all the [1, 0, 1, 0, 0, 1],
vertices/nodes might end up in the [0, 1, 0, 1, 1, 0],
queue at the same time. [0, 0, 1, 0, 1, 0],
[0, 0, 1, 1, 0, 1],
[1, 1, 0, 0, 1, 0]
]

def travBFS(graph, start):


visited = {}
queue = [start]
output = []
visited[start] = True

while len(queue) > 0:


current = queue.pop(0)
output.append(current)
current_idx = vertex_indices[current]

neighbours = graph[current_idx]
for i in range(len(neighbours)):
if neighbours[i] == 1 and vertices[i] not in visited:
queue.append(vertices[i])
visited[vertices[i]] = True

return output
D GRA DFS - You are given a graph Adjacency List Implementation
A PHS Iterat stored as an adjacency_list = {
Y2 ive adjacency list. Write 'A': ['B', 'F'],
4 and functions to traverse 'B': ['A', 'F', 'C'],
Recur the graph using the 'C': ['B', 'E', 'D'],
sive Depth first Search 'D': ['C', 'E'],
approach 'E': ['D', 'C', 'F'],
'F': ['A', 'B', 'E']
1) recursively and
}
2) iteratively.
As you traverse the Recursive
graph store the def trav_recursive_DFS(graph, vertex, output, visited):
values of the vertices # Append the current vertex to the output
in an array and output.append(vertex)
return this array.
# Mark the current vertex as visited
visited[vertex] = True

# Get all neighbors of the current vertex


neighbours = graph[vertex]

# For each neighbor of the current vertex


for neighbour in neighbours:
# If the neighbor has not been visited yet
if neighbour not in visited:
# Recursively perform DFS on the neighbor
trav_recursive_DFS(graph, neighbour, output, visited)

# Return the output list


return output

Iterative
# Iterative function for Depth-first search (DFS)
def trav_DFS_iterative(graph, start):
# Initialize the output list, visited dictionary and stack
output = []
visited = {}
stack = [start]

# Mark the start node as visited


visited[start] = True

# While there are nodes in the stack


while stack:
# Pop a node from the stack
current = stack.pop()

# Append the current node to the output


output.append(current)

# Get all neighbours of the current node


neighbours = graph[current]

# For each neighbour


for neighbour in neighbours:
# If the neighbour has not been visited yet
if neighbour not in visited:
# Push the neighbour to the stack
stack.append(neighbour)

# Mark the neighbour as visited


D GRA Num You are given a graph Count the Given a number of Vertices and a 2D def build_adj_list(n, edges): class Solution(object):
A PHS ber with n vertices. To Number of array. # Initialize adjacency list with empty
def adjList(self,
lists for each
n, edges):
vertex
Y2 of indicate the Complete From that 2D array, Form an adjacency adj_list = [[] for _ in range(n)] adj_list = [[] for _ in range(n)]
5 conn connections in the Componen list graph.
ected graph you are given ts - Adjacency list is a graph # Add edges to adjacency list for edge in edges:
comp an array edges LeetCode representation with dynamic arrays. for edge in edges: node1, node2 = edge
onent whose each element Let n = 5, arr = [[0,1][1,3],[2,3],[0,2], node1 = edge[0] # first node of edgeadj_list[node1].append(node2)
node2 = edge[1] # second node of adj_list[node2].append(node1)
edge
s is an array of the [1,4]]
adj_list[node1].append(node2)
form [u,v]. [u,v] Adjacencey List = [
adj_list[node2].append(node1) return adj_list
indicates that there [1,2],[3,4],[3,0],[1,2],[1]
is an edge between u ] return adj_list def dfs(self, graph, vertex, visited, component):
and v where u and v
denote two vertices consider this [[0,1][1,3],[2,3],[0,2]] -> def dfs(graph, vertex, visited): visited[vertex] = True
or nodes. Write a This is c a complete graph. So # Mark vertex as visited component.append(vertex)
function that takes in components = [0,1,2,3] visited[vertex] = True
‘n’ and the ‘edges’ for neighbor in graph[vertex]:
array and returns the Create a Visited = {} Object to store the # Get neighbors of current vertex if not visited[neighbor]:
number of visited values. neighbors = graph[vertex] self.dfs(graph, neighbor, visited, component)
connected Make count = 0
components in the Iterate from vertex = 0 to n # Visit all unvisited neighbors def is_complete(self, graph, component):
graph. If vertex is not visited, Increment the for neighbor in neighbors: for vertex1 in component:
count and call dfs. By calling dfs, The if neighbor not in visited: for vertex2 in component:
associated nodes with the vertices will dfs(graph, neighbor, visited) if vertex1 != vertex2 and vertex2 not in graph[vertex1]:
return False
be visited.
def count_components(n, edges): return True
Hence the count will not be
# Build adjacency list
incremented. graph = build_adj_list(n, edges)def countCompleteComponents(self, n, edges):
The count will only be incremented If graph = self.adjList(n, edges)
the node is not a part of the current # Initialize visited set visited = [False] * n
graph visited = {} count = 0
for vertex in range(n):
Time complexity explanation: count = 0 if not visited[vertex]:
The time complexity is O(V+E), where for vertex in range(n): component = []
V is the number of vertices and E is the if vertex not in visited: self.dfs(graph, vertex, visited, component)
number of edges. count += 1 if self.is_complete(graph, component):
Creating the adjacency list will take O dfs(graph, vertex, visited) count += 1
(E) time as we're iterating over all return count
edges. return count
DFS itself also has a time complexity of
O(V+E) because we're visiting every n = 7 # vertices 0, 1, 2, 3, 4, 5, 6
vertex once and checking all their edges = [[0,1],[1,2],[3,4],[5,6]]
print(count_components(n, edges))
neighbours (which corresponds to the
edges).

Space complexity explanation:


The space complexity is O(V+E).
The adjacency list will take O(V+E)
space. This is because we have a
separate list for each vertex, and the
total length of all lists is twice the
number of edges (since each edge
contributes to 2 vertices).
The visited dictionary will take O(V)
space as it could potentially store all
vertices.
There is also additional O(V) space
required for the call stack in the case
of a DFS on a connected graph.

So, overall, the space complexity is O


D GRA Cours You have to take a Course Brute Force Brute Force class Solution:
A PHS e total of n courses Schedule - Build an adjacency List from the givenfrom collections import deque def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
Y2 Sche leabled from 0 to n- LeetCode array. adjList = [[] for _ in range(numCourses)]
5 duler 1. Before you can # Time complexity: O(p)
Iterate over each vertex of the adjList, inDegree = [0 for _ in range(numCourses)]
/ take some courses where p is the number of
If It has a cycle, The course cannot be ans = []
Topol you need to take it’s finished. Return False. prerequisites.
ogical prerequisite courses. To check If It has a cycle, We need to# Space complexity: O(n), we for pres in prerequisites:
are creating an adjacency list first, second = pres
sort You are given an do Either BFS or DFS.
of n lists adjList[first].append(second)
array prerequisites For BFS, Create a queue and a vivisted
def buildAdjList(n, prerecs): inDegree[second] += 1
where each element map. adjList = [[] for _ in range
[x,y] indicates that to Do Normal BFS but add a condition if (n)] queue = []
take course x you the vertex of BFS(vertex, graph) == for prerec in prerecs: for i in range(numCourses):
have to take y first. E. curren = queue.popleft() toTake, firstTake = if(inDegree[i] == 0):
g. [2,3] indicates that If It is True, Has Cycle prerec queue.append(i)
to take course 2 one adjList[firstTake].append
has to first take Optimized Approach (toTake) while queue:
course 3. Write a For Optimized approac, We use return adjList current = queue.pop(0)
function that takes in Topological Sort # Final time complexity of ans.append(current)
n and the Topological Sort, We Create an array buildAdjList: O(n + p) neighbours = adjList[current]
prerequisite array inDegree, Where inDegree of a node is # Final space complexity of for neighbour in neighbours:
and returns true if the number of node coming to it. buildAdjList: O(n + p), as it inDegree[neighbour] -= 1
you can complete all Create an adjList and inDegree array needs to store 'p' if(inDegree[neighbour] == 0):
courses, else return with prerecs. prerequisites queue.append(neighbour)
false. Modified BFS
# Time complexity: O(E) return len(ans) == numCourses
It can be implmented using a stack or
where E is the total number of
queue = [] edges in the graph, since in
create an ans = [] the worst case
Iterate over inDegree array, If any # Space complexity: O(n), as
index is 0, append that index to the in the worst case scenario,
queue we might end up adding all
Iterate until queue is not empty nodes to the queue.
take the first element as current. # Additionally, we are also
append current to ans. maintaining a dictionary
take out the neighbours of current 'visited' which could contain
Iterate over each neighbour and all the nodes in the worst
reduce its inDegree case.
If it is 0, append it to the queue. we will visit all edges once
def checkCycleBFS(vertex,
return len(ans) == numCourses(n) graph):
queue = deque()
visited = {}
for i in range(len(graph
[vertex])):
queue.append(graph
[vertex][i])
while queue:
curr = queue.popleft()
visited[curr] = True
if curr == vertex:
return True
neighbours = graph[curr]
for neighbour in
neighbours:
if neighbour not in
visited:
queue.append
(neighbour)
return False
# Final time complexity of
checkCycleBFS: O(E + n)

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy