├── Level 2 ├── Dynamic Programming │ ├── Climbing stairs generalised.py │ ├── Climbing Stairs.py │ ├── Climbing Stairs dp.py │ ├── Ugly Number.py │ └── Ugly Number (optimised).py ├── Trees │ ├── Tree.png │ ├── Print all root to leaf paths.py │ └── Lowest common ancestor (LCA).py ├── Hashing │ ├── Frequency Sort.py │ ├── Relative Sorting (optimised).py │ ├── Find whether an array is subset of another array (duplicate elements).py │ ├── Sort an array based on order defined by another array (Relative Sorting).py │ └── Find whether an array is subset of another array (distinct elements).py ├── Array │ ├── Reverse an array in groups of given size.py │ ├── Leaders in an array.py │ ├── Equilibrium Point .py │ ├── Rearrange array alternatively in maximum and minimum form.py │ ├── Count the triplets.py │ ├── Subarray with given sum (positive and negative elements).py │ ├── Pythagorean Triplet in an array.py │ ├── Subarray with given sum (positive numbers).py │ └── Triplet sum.py ├── Maths │ ├── GCD of an array.py │ ├── LCM of an array.py │ ├── LCM of an array without using GCD.py │ ├── Sieve of Eratosthenes.py │ └── Computing value of nCr.py ├── String │ ├── Roman Numerals to Decimal.py │ ├── Length of the longest substring without repeating characters (Optimised).py │ ├── Longest Common Prefix.py │ ├── Check if string is rotated by two places.py │ ├── Remove all adjacent duplicates.py │ ├── Length of the longest substring without repeating characters.py │ ├── Remove all adjacent duplicates (recursive and optimised).py │ ├── Decimal to Roman Numerals.py │ ├── Length of the longest substring without repeating characters (Sliding Window Technique).py │ └── Reverse the string without reversing its individual words.py ├── Searching │ ├── Binary search (recursive).py │ ├── Find the element that appears once in a sorted array (binary search).py │ ├── Find the element that appears once in a sorted array.py │ ├── Searching in a nearly sorted rotated array.py │ └── How many times a sorted array is rotated.py ├── Stack and Queue │ ├── Prefix to Postfix Conversion.py │ ├── Prefix to Infix Conversion.py │ ├── Postfix to Infix Conversion.py │ ├── Postfix to Prefix Conversion.py │ ├── Infix to Postfix Conversion.py │ ├── Prefix expression evaluation.py │ └── Infix To Prefix Conversion.py ├── Greedy │ ├── Egyptian fraction.py │ ├── Huffman coding.py │ └── Huffman coding Sorted.py ├── Recursion │ ├── Generate all permutations of a string.py │ └── Generate all unique permutations of a string.py ├── Sorting │ ├── Segregate positive and negative integers using merge sort.py │ ├── Segregate positive and negative integers using merge sort optimised.py │ └── Inversion count of an array.py └── Linked List │ ├── Print Linked List in reverse order without reversing the Linked List.py │ ├── Swap pairwise nodes in a Linked List.py │ ├── Swap pairwise nodes in a Linked List without swapping data.py │ ├── Merge two Linked Lists at alternate positions.py │ ├── Insert at sorted position in a sorted Linked List.py │ ├── Check whether a Linked List is sorted or not.py │ └── Rotate the Linked List around a specific node.py ├── Level 1 ├── Searching │ ├── Find the number of 1’s in a sorted binary array.py.txt │ ├── Linear search.py │ ├── Binary search.py │ ├── Next Alphabetic Element.py │ ├── Find Pivot in rotated and sorted array.py │ ├── Ternary Search.py │ ├── Searching in an infinite sorted array.py │ ├── Index of first one in a binary sorted array.py │ ├── First and last occurrence of an element.py │ ├── Count of element in a sorted array.py │ ├── Floor, ceil of an element in array.py │ ├── Search in rotated and sorted array.py │ └── Order not known Search.py ├── Tree │ ├── Tree.png │ ├── Construction of a Tree.py │ ├── Delete a Binary Tree.py │ ├── Insertion of a node.py │ ├── Search in a tree.py │ ├── Height of tree.py │ ├── Sum of all nodes.py │ ├── Number of nodes.py │ ├── Preorder traversal recursive.py │ ├── Inorder traversal recursive.py │ ├── Postorder traversal recursive.py │ ├── Number of leaf nodes.py │ ├── Level order traversal.py │ └── Preorder traversal iterative.py ├── Recursion │ ├── Print numbers from n to 1 using recursion.py │ ├── Fibonacci Series.py │ ├── Print numbers from 1 to n using recursion.py │ ├── Reverse a given number.py │ ├── Power of Two (Recursive).py │ ├── Generating all subsets, powersets.py │ ├── Reverse an array, string using recursion.py │ ├── Generating all permutation with spaces.py │ ├── Generating all permutation with case change.py │ ├── Tower of Hanoi problem.py │ ├── Generating all unique subsets, powersets.py │ ├── Reverse a stack using recursion.py │ ├── Check if number is palindrome or not.py │ ├── Letter case Permutation.py │ ├── Sort an array using recursion.py │ ├── Factorial of a number.py │ └── Check if number is armstrong or not.py ├── Maths │ ├── Prime number.py │ ├── Power function.py │ ├── Factors of a number.py │ ├── Trailing zeroes in a factorial.py │ ├── Majority element.py │ ├── GCD.py │ ├── LCM.py │ ├── Grid Unique Paths.py │ └── Search in a sorted 2D matrix.py ├── Hashing │ ├── Hashing Basics.py │ ├── Find all symmetric pairs.py │ └── Two sum problem.py ├── Sorting │ ├── Bubble Sort.py │ ├── Insertion Sort.py │ ├── Selection Sort.py │ ├── Counting Sort.py │ ├── Quick Sort.py │ └── Merge Sort.py ├── Linked List │ ├── Making a linked list.py │ ├── Insertion Singly Linked List at start.py │ ├── Delete a Linked List.py │ ├── Print a Linked List.py │ ├── Length of Linked List iterative.py │ ├── Search in a Linked List.py │ ├── Insertion Singly Linked List at end.py │ ├── Doubly Linked List │ │ ├── Insertion doubly Linked List at start.py │ │ ├── Insertion doubly Linked List at end.py │ │ ├── Deletion doubly Linked List from start.py │ │ ├── Deletion doubly Linked List from end.py │ │ ├── Reverse a doubly linked list recursive.py │ │ ├── Reverse a doubly linked list iterative.py │ │ ├── Deletion doubly Linked List from middle.py │ │ └── Insertion doubly Linked List at middle.py │ ├── Loop in linked list using tortoise and hare algorithm.py │ ├── Deletion Singly Linked List from start.py │ ├── Loop in linked list using hashing.py │ ├── Circular Linked List │ │ ├── Insertion Circular Linked List at start.py │ │ ├── Insertion Circular Linked List from end.py │ │ ├── Deletion Circular Linked List from start.py │ │ └── Deletion Circular Linked List from end.py │ ├── Length of a linked list recursive.py │ ├── Start of the loop.py │ ├── Reverse a Linked List recursive.py │ ├── Reverse a Linked List iterative.py │ ├── Remove duplicates from a sorted linked list.py │ ├── Deletion Singly Linked List from end.py │ ├── Length of loop.py │ ├── Check length of Linked List is even or odd without couting nodes.py │ ├── Count of every element in a linked list.py │ ├── Find Nth Node from End of Linked list.py │ ├── Insertion Singly Linked List at middle.py │ ├── Delete a Linked List node without head pointer.py │ ├── Intersection of Two Linked List using stack.py │ └── Remove duplicates from a unsorted linked list.py ├── Greedy │ ├── What is a greedy approach.txt │ ├── Greedy algorithm to find minimum number of coins.py │ ├── N meeting in one room , Activity Selection Problem , Job Sequencing Problem.py │ └── Fractional Knapsack Problem .py ├── Bit Manipulation │ ├── Find element which appears once in array while all other appears twice.py │ ├── Bitwise operators Implementation.py │ ├── Convert binary to decimal.py │ ├── Number of 1 Bits or Hamming Weight.py │ ├── Missing Number in array.py │ ├── Convert decimal to decimal.py │ └── Power of Two.py ├── Array │ ├── Remove duplicates from array of integer.py │ ├── Find the first repeating element in an array of integers.py │ ├── Find duplicate elements in array.py │ ├── Find non repeated element in array of integers.py │ ├── Find the first non repeating element in an array of integers.py │ ├── Find unique elements in an array.py │ ├── nth row col of a matrix.py │ ├── Reverse the given input array.py │ ├── Upper, lower triangular matrix.py │ ├── Merge two sorted array to form single array.py │ ├── Move all the negative elements to one side of the array.py │ ├── Check whether given array is sorted or not.py │ ├── Transpose of a Matrix.py │ ├── Sort the array of 0s, 1s, and 2s.py │ ├── Move all 0s to end of the array.py │ ├── Find the minimum and maximum element in an array.py │ ├── Find most frequent element in array.py │ ├── Segregate 0's and 1's in an array.py │ ├── Find missing number in integer array of 1 to 100.py │ └── Diagonal of a matrix.py ├── Dynamic Programming │ ├── Longest common subsequnce Recursive.py │ ├── 0-1 Knapsack Recursive.py │ ├── Longest common subsequnce Memorized.py │ ├── Subset sum problem.py │ ├── Fibonnaci series.py │ ├── What is Dynamic Programming.txt │ ├── Coin change max ways.py │ ├── Longest common subsequnce Tabular.py │ ├── Count subsets with given sum.py │ ├── Shortest common supersequence.py │ ├── 0-1 Knapsack Memorized.py │ ├── Longest common substring O(n^2).py │ ├── Coin change min ways.py │ ├── 0-1 Knapsack Tabular.py │ ├── Equal sum partition problem.py │ ├── Printing LCS.py │ └── Maximum Subarray sum (Kadane Algorithm).py ├── Graph │ ├── Graph data structure.py │ ├── DFS Traversal.py │ ├── BFS Traversal.py │ ├── BFS Traversal for disconnected graph.py │ ├── DFS Traversal for disconnected graph.py │ └── Implementation of graph.py ├── String │ ├── Remove a given character from String.py │ ├── String Expansion.py │ ├── Find first non-repeating character of given string.py │ ├── Remove all duplicates from given string.py │ ├── String Compression.py │ ├── Check if given string has all unique characters.py │ ├── Reverse a string.py │ ├── Check if a string is substring of another or not.py │ ├── Check if given string is pallindrome or not.py │ ├── Print duplicate characters of given string.py │ ├── Find maximum ocurring charater in given string.py │ ├── Generate all substrings of a string.py │ ├── Check if two string are rotation of each other or not.py │ └── Check if one string is permutation of the other or not.py ├── Stack & Queue │ ├── Implementing queue and its operations.py │ ├── Next greater to left.py │ ├── Next smaller to left.py │ ├── Implementating stack and its operations.py │ ├── Parenthesis checker.py │ ├── Implementing Stack using linked list.py │ ├── Next greater to right.py │ ├── Next smaller to right.py │ └── Implementing Queue using linked list.py ├── Space complexity │ ├── Materials.txt │ └── Code │ │ └── Fibonacci Variations.py ├── Heap │ └── Implementing Heap.py └── Time complexity │ └── Materials.txt └── README.md /Level 2/Dynamic Programming/Climbing stairs generalised.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Level 1/Searching/Find the number of 1’s in a sorted binary array.py.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Level 1/Tree/Tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marvel2950/Data-Structures-and-Algorithms-Problems/HEAD/Level 1/Tree/Tree.png -------------------------------------------------------------------------------- /Level 2/Trees/Tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marvel2950/Data-Structures-and-Algorithms-Problems/HEAD/Level 2/Trees/Tree.png -------------------------------------------------------------------------------- /Level 1/Recursion/Print numbers from n to 1 using recursion.py: -------------------------------------------------------------------------------- 1 | def printNumbers(n): 2 | if n==1: 3 | print(1) 4 | return 5 | print(n) 6 | printNumbers(n-1) 7 | printNumbers(8) -------------------------------------------------------------------------------- /Level 1/Recursion/Fibonacci Series.py: -------------------------------------------------------------------------------- 1 | def fibonacci(n): 2 | if n==1: 3 | return 0 4 | elif n==2: 5 | return 1 6 | return fibonacci(n-1)+fibonacci(n-2) 7 | 8 | print(fibonacci(5)) -------------------------------------------------------------------------------- /Level 1/Recursion/Print numbers from 1 to n using recursion.py: -------------------------------------------------------------------------------- 1 | def printNumbers(n): 2 | if n==1: 3 | print(1) 4 | return 5 | printNumbers(n-1) 6 | print(n) 7 | 8 | printNumbers(5) -------------------------------------------------------------------------------- /Level 2/Dynamic Programming/Climbing Stairs.py: -------------------------------------------------------------------------------- 1 | def fib(n): 2 | if n<=1: 3 | return n 4 | else: 5 | return fib(n-1)+fib(n-2) 6 | 7 | def ways(s): 8 | return fib(s+1) 9 | 10 | s = 4 11 | print(ways(s)) -------------------------------------------------------------------------------- /Level 1/Maths/Prime number.py: -------------------------------------------------------------------------------- 1 | import math 2 | def isPrime(n): 3 | if n<=1: 4 | return False 5 | for i in range(2,int(math.sqrt(n))+1): 6 | if n%i==0: 7 | return False 8 | return True 9 | 10 | n = 4 11 | flag = isPrime(n) 12 | print(flag) -------------------------------------------------------------------------------- /Level 1/Recursion/Reverse a given number.py: -------------------------------------------------------------------------------- 1 | op = 0 2 | def reverseANumber(n): 3 | global op 4 | if n<10: 5 | op = op*10+n 6 | return 7 | op = op*10+n%10 8 | reverseANumber(n//10) 9 | 10 | reverseANumber(3456) 11 | print(op) -------------------------------------------------------------------------------- /Level 1/Recursion/Power of Two (Recursive).py: -------------------------------------------------------------------------------- 1 | def powerOfTwo(n): 2 | if n==0: 3 | return 1 4 | elif n%2==0: 5 | return powerOfTwo(n//2)*powerOfTwo(n//2) 6 | else: 7 | return 2*powerOfTwo(n//2)*powerOfTwo(n//2) 8 | print(powerOfTwo(5)) -------------------------------------------------------------------------------- /Level 1/Hashing/Hashing Basics.py: -------------------------------------------------------------------------------- 1 | d = {} 2 | d[1] = 5 3 | d[6] = 8 4 | print(d) 5 | for i,j in d.items(): 6 | print(i,j) 7 | print(list(d.keys())) 8 | print(d.values()) 9 | 10 | d[6] = 'r' 11 | print(d) 12 | 13 | if 9 in d: 14 | print("Yes") 15 | else: 16 | print("No") -------------------------------------------------------------------------------- /Level 1/Sorting/Bubble Sort.py: -------------------------------------------------------------------------------- 1 | def bubbleSort(arr): 2 | for i in range(len(arr)): 3 | for j in range(len(arr)-i-1): 4 | if arr[j]>arr[j+1]: 5 | arr[j],arr[j+1] = arr[j+1],arr[j] 6 | 7 | 8 | arr = [5,1,2,4,7,6] 9 | bubbleSort(arr) 10 | print(*arr) -------------------------------------------------------------------------------- /Level 1/Linked List/Making a linked list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | 11 | 12 | l = LinkedList() 13 | print(l.head) -------------------------------------------------------------------------------- /Level 1/Recursion/Generating all subsets, powersets.py: -------------------------------------------------------------------------------- 1 | def subsetOfAString(ip,op): 2 | if len(ip)==0: 3 | print("String",op) 4 | return 5 | subsetOfAString(ip[1:],op+ip[0]) 6 | subsetOfAString(ip[1:],op) 7 | 8 | ip = 'abc' 9 | op = '' 10 | subsetOfAString(ip,op) -------------------------------------------------------------------------------- /Level 1/Sorting/Insertion Sort.py: -------------------------------------------------------------------------------- 1 | def insertionSort(arr): 2 | for i in range(len(arr)): 3 | j = i-1 4 | while j>=0 and arr[j]>arr[j+1]: 5 | arr[j],arr[j+1] = arr[j+1],arr[j] 6 | j-=1 7 | 8 | arr = [5,4,3,2,1] 9 | insertionSort(arr) 10 | print(arr) -------------------------------------------------------------------------------- /Level 2/Hashing/Frequency Sort.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | def frequencySort(arr): 4 | d = defaultdict(lambda:0) 5 | for i in range(len(arr)): 6 | d[arr[i]] += 1 7 | arr.sort(key=lambda x:(-d[x],x)) 8 | 9 | arr = [8,7,8,7,8,5,4] 10 | frequencySort(arr) 11 | print(arr) -------------------------------------------------------------------------------- /Level 1/Searching/Linear search.py: -------------------------------------------------------------------------------- 1 | def linearSearch(arr,ele): 2 | ind = -1 3 | for i in range(0,len(arr)): 4 | if arr[i]==ele: 5 | ind = i 6 | break 7 | return ind 8 | 9 | arr = [1,0,55,6,2,7] 10 | ele = 6 11 | index = linearSearch(arr,ele) 12 | print(index) -------------------------------------------------------------------------------- /Level 1/Tree/Construction of a Tree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.left = None 5 | self.right = None 6 | 7 | class Tree: 8 | def __init__(self): 9 | self.root = None 10 | 11 | tree = Tree() 12 | print(tree.root) -------------------------------------------------------------------------------- /Level 1/Recursion/Reverse an array, string using recursion.py: -------------------------------------------------------------------------------- 1 | def reverseAnArray(ip_array): 2 | if len(ip_array)==1: 3 | return 4 | alpha = ip_array.pop(0) 5 | reverseAnArray(ip_array) 6 | ip_array.append(alpha) 7 | 8 | ip_array = [1,2,3] 9 | reverseAnArray(ip_array) 10 | print(ip_array) -------------------------------------------------------------------------------- /Level 1/Sorting/Selection Sort.py: -------------------------------------------------------------------------------- 1 | def selectionSort(arr): 2 | for i in range(len(arr)): 3 | fixed = i 4 | for j in range(i+1,len(arr)): 5 | if arr[fixed]>arr[j]: 6 | arr[fixed],arr[j] = arr[j],arr[fixed] 7 | 8 | arr = [5,4,3,2,1] 9 | selectionSort(arr) 10 | print(arr) -------------------------------------------------------------------------------- /Level 1/Greedy/What is a greedy approach.txt: -------------------------------------------------------------------------------- 1 | What is a Greedy approach ? 2 | 3 | Greedy is an algorithmic paradigm that builds up a solution piece by piece, always choosing the next piece that offers the most obvious and immediate benefit. So the problems where choosing locally optimal also leads to global solution are best fit for Greedy. -------------------------------------------------------------------------------- /Level 1/Recursion/Generating all permutation with spaces.py: -------------------------------------------------------------------------------- 1 | def permuatationWithSpaces(ip,op): 2 | if len(ip)==0: 3 | print(op) 4 | return 5 | permuatationWithSpaces(ip[1:],op+" "+ip[0]) 6 | permuatationWithSpaces(ip[1:],op+ip[0]) 7 | 8 | 9 | ip ='abc' 10 | op = '' 11 | permuatationWithSpaces(ip[1:],ip[0]) -------------------------------------------------------------------------------- /Level 1/Recursion/Generating all permutation with case change.py: -------------------------------------------------------------------------------- 1 | def permutationWithCaseChange(ip,op): 2 | if len(ip)==0: 3 | print(op) 4 | return 5 | permutationWithCaseChange(ip[1:],op+ip[0].upper()) 6 | permutationWithCaseChange(ip[1:],op+ip[0]) 7 | 8 | ip = 'ab' 9 | op = '' 10 | permutationWithCaseChange(ip,op) -------------------------------------------------------------------------------- /Level 1/Recursion/Tower of Hanoi problem.py: -------------------------------------------------------------------------------- 1 | def towerOfHanoi(source,dest,hel,n): 2 | if n==1: 3 | print("Plate",n,"from",source,"to",dest) 4 | return 5 | towerOfHanoi(source,hel,dest,n-1) 6 | print("Plate",n,"from",source,"to",dest) 7 | towerOfHanoi(hel,dest,source,n-1) 8 | 9 | 10 | towerOfHanoi('s','d','h',3) -------------------------------------------------------------------------------- /Level 1/Recursion/Generating all unique subsets, powersets.py: -------------------------------------------------------------------------------- 1 | hash_map = {} 2 | def subsetsOfAString(ip,op): 3 | if len(ip)==0: 4 | hash_map[op] = 1 5 | return 6 | subsetsOfAString(ip[1:],op+ip[0]) 7 | subsetsOfAString(ip[1:],op) 8 | ip = 'abb' 9 | op = '' 10 | subsetsOfAString(ip,op) 11 | print(list(hash_map.keys())) -------------------------------------------------------------------------------- /Level 1/Bit Manipulation/Find element which appears once in array while all other appears twice.py: -------------------------------------------------------------------------------- 1 | def eleOccursOnce(arr): 2 | xor_val = 0 3 | for i in arr: 4 | xor_val=xor_val^i 5 | ele = xor_val 6 | return ele 7 | 8 | arr = [1,1,2,3,4,3,2,5,6,7,8,7,6,8,4] 9 | print(sorted(arr)) 10 | ele = eleOccursOnce(arr) 11 | print(ele) -------------------------------------------------------------------------------- /Level 1/Bit Manipulation/Bitwise operators Implementation.py: -------------------------------------------------------------------------------- 1 | a = 4 2 | b = 5 3 | 4 | and_val = a&b 5 | print(and_val) 6 | 7 | or_val = a|b 8 | print(or_val) 9 | 10 | xor_val = a^b 11 | print(xor_val) 12 | 13 | not_val = ~b 14 | print(not_val) 15 | 16 | left_shift = a<<3 17 | print(left_shift) 18 | 19 | right_shift = a>>2 20 | print(right_shift) -------------------------------------------------------------------------------- /Level 1/Array/Remove duplicates from array of integer.py: -------------------------------------------------------------------------------- 1 | def removeDup(ip_arr): 2 | ins = {} 3 | i = 0 4 | while i=0: 7 | while v>=deno[i]: 8 | v -= deno[i] 9 | ans.append(deno[i]) 10 | i-=1 11 | return ans 12 | 13 | v = 93 14 | deno = [1,2000,500,2,10,20,50,100,5] 15 | change = minCoins(v,deno) 16 | print(change) -------------------------------------------------------------------------------- /Level 1/Recursion/Letter case Permutation.py: -------------------------------------------------------------------------------- 1 | def letterCasePermutation(ip,op): 2 | if len(ip)==0: 3 | print(op) 4 | return 5 | 6 | if ip[0] in '1234567890': 7 | letterCasePermutation(ip[1:],op+ip[0]) 8 | else: 9 | letterCasePermutation(ip[1:],op+ip[0]) 10 | letterCasePermutation(ip[1:],op+ip[0].upper()) 11 | 12 | ip = 'a1b2' 13 | op = '' 14 | letterCasePermutation(ip,op) -------------------------------------------------------------------------------- /Level 1/String/String Expansion.py: -------------------------------------------------------------------------------- 1 | def expansion(ip_str): 2 | if len(ip_str)<=1 or len(ip_str)%2!=0: 3 | return '' 4 | op = [] 5 | for i in range(0,len(ip_str),2): 6 | chr = ip_str[i] 7 | count = int(ip_str[i+1]) 8 | for j in range(count): 9 | op.append(chr) 10 | op = ''.join(op) 11 | return op 12 | 13 | 14 | ip_str = "a2b1c5a3" 15 | op = expansion(ip_str) 16 | print(op) -------------------------------------------------------------------------------- /Level 1/Recursion/Sort an array using recursion.py: -------------------------------------------------------------------------------- 1 | def insert(arr,alpha): 2 | if len(arr)==0 or arr[-1]1: 11 | ans.append(nu) 12 | return ans 13 | 14 | ip_arr = [1,7,7,5,2,2,9] 15 | op_arr = duplicateEle(ip_arr) 16 | print(op_arr) -------------------------------------------------------------------------------- /Level 1/Bit Manipulation/Convert binary to decimal.py: -------------------------------------------------------------------------------- 1 | def binaryToDecimal(num): 2 | dec_num = 0 3 | for i in range(len(num)): 4 | if num[i]=='1': 5 | x = (2*int(num[i])) 6 | n = len(num)-1-i 7 | dec_num = dec_num + x**n 8 | return dec_num 9 | 10 | bin_num = '10110' 11 | 12 | dec_num = binaryToDecimal(bin_num) 13 | print(dec_num) 14 | 15 | dec_num = int(bin_num,2) 16 | print(dec_num) 17 | -------------------------------------------------------------------------------- /Level 2/Maths/GCD of an array.py: -------------------------------------------------------------------------------- 1 | def gcd(a,b): 2 | if b==0: 3 | return a 4 | return gcd(b,a%b) 5 | 6 | def gcdArray(arr): 7 | if len(arr)==0: 8 | return -1 9 | res = arr[0] 10 | for i in range(1,len(arr)): 11 | if arr[i]==1: 12 | res = 1 13 | break 14 | res = gcd(res,arr[i]) 15 | return res 16 | 17 | arr = [2,4,6,8,16] 18 | gcdVal = gcdArray(arr) 19 | print(gcdVal) 20 | 21 | -------------------------------------------------------------------------------- /Level 1/Sorting/Counting Sort.py: -------------------------------------------------------------------------------- 1 | def countSort(arr,b,k): 2 | count = [0]*(k+2) 3 | for i in arr: 4 | count[i] = count[i]+1 5 | for i in range(1,k+1): 6 | count[i] = count[i-1]+count[i] 7 | 8 | for i in range(len(arr)-1,-1,-1): 9 | b[count[arr[i]]-1] = arr[i] 10 | count[arr[i]] = count[arr[i]]-1 11 | 12 | 13 | arr = [3,2,3,2,3,4,1,1] 14 | k = max(arr) 15 | b = [0]*len(arr) 16 | countSort(arr,b,k) 17 | print(b) -------------------------------------------------------------------------------- /Level 1/Recursion/Factorial of a number.py: -------------------------------------------------------------------------------- 1 | #Iterative approach 2 | def factorial_itertive(n): 3 | fact = 1 4 | for i in range(n,0,-1): 5 | fact=fact*i 6 | return fact 7 | 8 | #Recursive approach 9 | def factorial_recursive(n): 10 | if n==1: 11 | return 1 12 | return n*factorial_recursive(n-1) 13 | 14 | 15 | n = 5 16 | fact1 = factorial_itertive(n) 17 | print(fact1) 18 | 19 | fact2 = factorial_recursive(n) 20 | print(fact2) -------------------------------------------------------------------------------- /Level 1/Array/Find non repeated element in array of integers.py: -------------------------------------------------------------------------------- 1 | def nonRepeatingEle(ip_arr): 2 | count = {} 3 | for i in ip_arr: 4 | if i not in count: 5 | count[i] = 1 6 | else: 7 | count[i] = count[i]+1 8 | ans = [] 9 | for nu,co in count.items(): 10 | if co==1: 11 | ans.append(nu) 12 | return ans 13 | 14 | ip_arr = [1,7,7,5,2,2,9] 15 | op_arr = nonRepeatingEle(ip_arr) 16 | print(op_arr) -------------------------------------------------------------------------------- /Level 1/String/Find first non-repeating character of given string.py: -------------------------------------------------------------------------------- 1 | def firstNonRepeating(ip): 2 | count = {} 3 | for i in ip: 4 | if i not in count: 5 | count[i] = 1 6 | else: 7 | count[i] = count[i]+1 8 | ans = '' 9 | for i in ip: 10 | if count[i]==1: 11 | ans = i 12 | break 13 | return ans 14 | 15 | 16 | ip = "abccabaaadd" 17 | op = firstNonRepeating(ip) 18 | print("Op",op) -------------------------------------------------------------------------------- /Level 2/Maths/LCM of an array.py: -------------------------------------------------------------------------------- 1 | def gcd(a,b): 2 | if b==0: 3 | return a 4 | return gcd(b,a%b) 5 | 6 | def lcm(a,b): 7 | return a*b//gcd(a,b) 8 | 9 | def lcmArray(arr): 10 | if len(arr)<2: 11 | return -1 12 | num1 = arr[0] 13 | num2 = arr[1] 14 | lcmVal = lcm(num1,num2) 15 | for i in range(2,len(arr)): 16 | lcmVal = lcm(lcmVal,arr[i]) 17 | return lcmVal 18 | 19 | arr = [1, 2, 3, 4, 28] 20 | lcmVal = lcmArray(arr) 21 | print(lcmVal) -------------------------------------------------------------------------------- /Level 1/Bit Manipulation/Number of 1 Bits or Hamming Weight.py: -------------------------------------------------------------------------------- 1 | def countOne(n): 2 | bin_num = bin(n)[2:] 3 | count = 0 4 | for i in bin_num: 5 | if i=='1': 6 | count+=1 7 | return count 8 | 9 | n = 23 10 | oneBits = countOne(n) 11 | print(oneBits) 12 | 13 | def countOne2(n): 14 | count = 0 15 | while n: 16 | n = n&(n-1) 17 | count+=1 18 | return count 19 | 20 | n = 23 21 | oneBits = countOne2(n) 22 | print(oneBits) -------------------------------------------------------------------------------- /Level 1/Tree/Delete a Binary Tree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.right = None 5 | self.left = None 6 | 7 | def delete(root): 8 | if root==None: 9 | return 10 | delete(root.left) 11 | delete(root.right) 12 | del root 13 | 14 | 15 | root = Node(1) 16 | root.left = Node(2) 17 | root.right = Node(3) 18 | root.left.left = Node(4) 19 | root.right.left = Node(5) 20 | delete(root) 21 | root = None -------------------------------------------------------------------------------- /Level 2/String/Roman Numerals to Decimal.py: -------------------------------------------------------------------------------- 1 | def romanToDecimal(rom): 2 | value = { 3 | 'M':1000, 4 | 'D':500, 5 | 'C':100, 6 | 'L':50, 7 | 'X':10, 8 | 'V':5, 9 | 'I':1 10 | } 11 | 12 | prev = 0 13 | dec = 0 14 | for i in range(len(rom)-1,-1,-1): 15 | if value[rom[i]]>=prev: 16 | dec+=value[rom[i]] 17 | else: 18 | dec-=value[rom[i]] 19 | prev = value[rom[i]] 20 | return dec 21 | 22 | roman = 'MCMIV' 23 | decimal = romanToDecimal(roman) 24 | print(decimal) -------------------------------------------------------------------------------- /Level 2/Hashing/Relative Sorting (optimised).py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | def sortRelative(arr1,arr2): 4 | res = [] 5 | f = Counter(arr1) 6 | 7 | for i in arr2: 8 | res.extend([i]*f[i]) 9 | f[i] = 0 10 | rem = list(sorted((filter(lambda x:f[x] != 0,f.keys())))) 11 | for i in rem: 12 | res.extend([i]*f[i]) 13 | return res 14 | 15 | arr1 = [2,1,2,5,7,1,9,3,6,8,8] 16 | arr2 = [2,1,8,3] 17 | res = sortRelative(arr1,arr2) 18 | print(res) -------------------------------------------------------------------------------- /Level 2/String/Length of the longest substring without repeating characters (Optimised).py: -------------------------------------------------------------------------------- 1 | def longestUniqueSubstring(str): 2 | seen = {} 3 | maxLength = 0 4 | start = 0 5 | for end in range(len(str)): 6 | if str[end] in seen: 7 | start = max(start,seen[str[end]]+1) 8 | seen[str[end]] = end 9 | maxLength = max(maxLength,end-start+1) 10 | return maxLength 11 | 12 | str = "ABDEFGABEF" 13 | lenStr = longestUniqueSubstring(str) 14 | print(lenStr) -------------------------------------------------------------------------------- /Level 2/String/Longest Common Prefix.py: -------------------------------------------------------------------------------- 1 | def commonPrefixUtil(str1,str2): 2 | res = '' 3 | i = 0 4 | j = 0 5 | while icount: 20 | i += 1 21 | if isUgly(i): 22 | count += 1 23 | return i 24 | 25 | n = 10 26 | num = nthUglyNum(n) 27 | print(num) -------------------------------------------------------------------------------- /Level 1/String/Remove all duplicates from given string.py: -------------------------------------------------------------------------------- 1 | def removeAllDuplicates(ip): 2 | count = {} 3 | for i in ip: 4 | if i not in count: 5 | count[i]=1 6 | else: 7 | count[i]=count[i]+1 8 | ip = list(ip) 9 | i = 0 10 | while i1: 12 | ip.pop(i) 13 | else: 14 | i=i+1 15 | ip=''.join(ip) 16 | return ip 17 | 18 | ip = "abcabaaa" 19 | op = removeAllDuplicates(ip) 20 | print(op) -------------------------------------------------------------------------------- /Level 1/Linked List/Insertion Singly Linked List at start.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtStart(self,data): 11 | newNode = Node(data) 12 | newNode.next =self.head 13 | self.head = newNode 14 | 15 | l = LinkedList() 16 | nodes_val = [1,2,3,4,5] 17 | for i in nodes_val: 18 | l.insertAtStart(i) 19 | 20 | print(l.head.val) -------------------------------------------------------------------------------- /Level 1/Array/Find unique elements in an array.py: -------------------------------------------------------------------------------- 1 | def uniqueEle1(ip_arr): 2 | ins = {} 3 | for i in ip_arr: 4 | ins[i] = True 5 | # ans = [] 6 | # for key,value in ins.items(): 7 | # ans.append(key) 8 | ans = list(ins.keys()) 9 | return ans 10 | 11 | ip_arr = [1,7,7,5,2,2,9] 12 | op_arr = uniqueEle1(ip_arr) 13 | print(op_arr) 14 | 15 | def uniqueEle2(ip_arr): 16 | ans = list(set(ip_arr)) 17 | return ans 18 | 19 | ip_arr = [1,7,7,5,2,2,9] 20 | op_arr = uniqueEle2(ip_arr) 21 | print(op_arr) -------------------------------------------------------------------------------- /Level 2/Searching/Binary search (recursive).py: -------------------------------------------------------------------------------- 1 | def binarySearch(arr,ele,start,end): 2 | if end >= start: 3 | mid = (start + end)//2 4 | if arr[mid] == ele: 5 | return mid 6 | elif arr[mid]>ele: 7 | return binarySearch(arr,ele,start,mid-1) 8 | else: 9 | return binarySearch(arr,ele,mid+1,end) 10 | else: 11 | return -1 12 | 13 | arr = [1,2,5,6,9,14] 14 | ele = 9 15 | start = 0 16 | end = len(arr)-1 17 | ind = binarySearch(arr,ele,start,end) 18 | print(ind) -------------------------------------------------------------------------------- /Level 2/Maths/LCM of an array without using GCD.py: -------------------------------------------------------------------------------- 1 | def lcmArray(arr): 2 | n = len(arr) 3 | maxNum = max(arr) 4 | res = 1 5 | x = 2 6 | while x <= maxNum: 7 | ind = [] 8 | for j in range(n): 9 | if arr[j] % x == 0: 10 | ind.append(j) 11 | if len(ind) >= 2: 12 | for j in range(len(ind)): 13 | arr[ind[j]] = arr[ind[j]] // x 14 | res = res * x 15 | else: 16 | x += 1 17 | for i in range(n): 18 | res = res * arr[i] 19 | 20 | return res 21 | 22 | arr = [1, 2, 3, 4, 28] 23 | lcmVal = lcmArray(arr) 24 | print(lcmVal) -------------------------------------------------------------------------------- /Level 1/String/String Compression.py: -------------------------------------------------------------------------------- 1 | def compression(ip_str): 2 | if len(ip_str)==0: 3 | return '' 4 | last = ip_str[0] 5 | c = 1 6 | op = [] 7 | for i in range(1,len(ip_str)): 8 | if ip_str[i]==last: 9 | c=c+1 10 | else: 11 | op.append(last) 12 | op.append(str(c)) 13 | last = ip_str[i] 14 | c = 1 15 | op.append(last) 16 | op.append(str(c)) 17 | op = ''.join(op) 18 | return op 19 | 20 | ip_str = 'aabcccccaaa' 21 | op = compression(ip_str) 22 | print(op) -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/0-1 Knapsack Recursive.py: -------------------------------------------------------------------------------- 1 | def knapsack(weight,value,wt,n): 2 | if n==0 or wt==0: 3 | return 0 4 | if weight[n-1]<=wt: 5 | return max( 6 | value[n-1]+ 7 | knapsack(weight,value,wt-weight[n-1],n-1), 8 | knapsack(weight,value,wt,n-1) 9 | ) 10 | elif weight[n-1]>wt: 11 | return knapsack(weight,value,wt,n-1) 12 | 13 | weight = [1,3,4,5] 14 | value = [1,4,5,7] 15 | wt = 7 16 | n = len(weight) 17 | 18 | val = knapsack(weight,value,wt,n) 19 | print(val) 20 | -------------------------------------------------------------------------------- /Level 1/Sorting/Quick Sort.py: -------------------------------------------------------------------------------- 1 | def partition(arr,low,high): 2 | i = low-1 3 | pivot = arr[high] 4 | for j in range(low,high): 5 | if arr[j]=len(mat): 3 | return -1 4 | row = [] 5 | for i in range(len(mat)): 6 | row.append(mat[n-1][i]) 7 | return row 8 | 9 | def nthCol(mat,n): 10 | if n>=len(mat): 11 | return -1 12 | col = [] 13 | for i in range(len(mat)): 14 | col.append(mat[i][n-1]) 15 | return col 16 | 17 | 18 | mat = [ 19 | [1,2,3], 20 | [4,5,6], 21 | [7,8,9] 22 | ] 23 | 24 | n = 2 25 | row = nthRow(mat,n) 26 | print(row) 27 | col = nthCol(mat,n) 28 | print(col) -------------------------------------------------------------------------------- /Level 1/Searching/Next Alphabetic Element.py: -------------------------------------------------------------------------------- 1 | def nextAlphabeticalElement(string,key,start,end): 2 | res = -1 3 | while start <= end: 4 | mid = (start+end)//2 5 | if key==string[mid]: 6 | start = mid+1 7 | elif key < string[mid]: 8 | res = string[mid] 9 | end = mid-1 10 | elif key > string[mid]: 11 | start = mid+1 12 | return res 13 | 14 | string = 'abchjoqt' 15 | key = 'd' 16 | start = 0 17 | end = len(string)-1 18 | nextAlpha = nextAlphabeticalElement(string,key,start,end) 19 | print(nextAlpha) -------------------------------------------------------------------------------- /Level 2/Stack and Queue/Prefix to Postfix Conversion.py: -------------------------------------------------------------------------------- 1 | def prefixToPostfix(prefixExp): 2 | stack = [] 3 | i = len(prefixExp)-1 4 | while i>=0: 5 | if prefixExp[i].isalpha(): 6 | stack.append(prefixExp[i]) 7 | else: 8 | alpha = stack.pop(-1) 9 | beta = stack.pop(-1) 10 | strUtil = alpha + beta + prefixExp[i] 11 | stack.append(strUtil) 12 | i-=1 13 | print("Stack",stack) 14 | return stack[0] 15 | 16 | prefixExp = "*+ab-cd" 17 | postExp = prefixToPostfix(prefixExp) 18 | print(postExp) -------------------------------------------------------------------------------- /Level 2/String/Remove all adjacent duplicates.py: -------------------------------------------------------------------------------- 1 | def removeAdjacentDuplicates(str): 2 | str = list(str) 3 | flag = True 4 | while flag: 5 | i = 0 6 | check = False 7 | while i=0: 5 | if prefixExp[i].isalpha(): 6 | stack.append(prefixExp[i]) 7 | else: 8 | alpha = stack.pop(-1) 9 | beta = stack.pop(-1) 10 | strUtil = "(" + alpha + prefixExp[i] + beta + ")" 11 | stack.append(strUtil) 12 | i-=1 13 | print("Stack",stack) 14 | return stack[0] 15 | 16 | prefixExp = "*+ab-cd" 17 | infixExp = prefixToInfix(prefixExp) 18 | print(infixExp) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data-Structures-and-Algorithms-Problems 2 | 3 | This Repository contains frequently asked Data Structure Algorithm Questions in an interview divided broadly into two levels covering more than 450 problems. 4 | 5 | Topics Covered : 6 | 1. Recursion 7 | 2. Linked List 8 | 3. Trees 9 | 4. Sorting 10 | 5. Searching 11 | 6. Heap Data Structure 12 | 7. Stack and Queue Data Structure 13 | 8. Greedy Algorithms 14 | 9. Array 15 | 10. Strings 16 | 11. Graphs 17 | 12. Time Complexity 18 | 13. Hashing 19 | 14. Maths 20 | 15. Dynamic Programming 21 | 16. Bit Manipulation -------------------------------------------------------------------------------- /Level 1/Stack & Queue/Implementing queue and its operations.py: -------------------------------------------------------------------------------- 1 | class Queue: 2 | def __init__(self): 3 | self.q = [] 4 | 5 | def enque(self,data): 6 | self.q.append(data) 7 | 8 | def deque(self): 9 | popEle = -1 10 | if len(self.q)>0: 11 | popEle = self.q.pop(0) 12 | return popEle 13 | 14 | def print(self): 15 | for i in self.q: 16 | print(i,end=" ") 17 | print() 18 | 19 | q = Queue() 20 | q.enque(5) 21 | q.enque(6) 22 | q.enque(7) 23 | q.enque(8) 24 | q.print() 25 | q.deque() 26 | q.deque() 27 | q.print() -------------------------------------------------------------------------------- /Level 2/Stack and Queue/Postfix to Infix Conversion.py: -------------------------------------------------------------------------------- 1 | def postfixToInfix(postfixExp): 2 | stack = [] 3 | i = 0 4 | while iarr[i]: 8 | op.append(stack[-1]) 9 | else: 10 | while len(stack)>0 and stack[-1]0 and stack[-1]>arr[i]: 11 | stack.pop(-1) 12 | if len(stack)==0: 13 | op.append(-1) 14 | else: 15 | op.append(stack[-1]) 16 | stack.append(arr[i]) 17 | return op 18 | 19 | arr = [1,3,2,4] 20 | op = solve(arr) 21 | print(op) -------------------------------------------------------------------------------- /Level 1/Array/Reverse the given input array.py: -------------------------------------------------------------------------------- 1 | def reverse1(ip_arr): 2 | op_arr = [-1]*len(ip_arr) #[-1,-1,-1,-1,-1] 3 | j = 0 4 | for i in range(len(ip_arr)-1,-1,-1): 5 | op_arr[j] = ip_arr[i] 6 | j=j+1 7 | return op_arr 8 | 9 | ip_arr = [1,2,3,4,5] 10 | op_arr = reverse1(ip_arr) 11 | print(op_arr) 12 | 13 | def reverse2(ip_arr): 14 | i = 0 15 | j = len(ip_arr)-1 16 | while i last_time: 11 | order.append(alpha[i]) 12 | last_time = alpha[i][1] 13 | return order 14 | 15 | 16 | start_time = [1,3,0,5,8,5] 17 | end_time = [2,4,6,7,9,9] 18 | order = solve(start_time,end_time) 19 | print(order) -------------------------------------------------------------------------------- /Level 2/Greedy/Egyptian fraction.py: -------------------------------------------------------------------------------- 1 | import math 2 | def egyptianFraction(num,den): 3 | denVals = [] 4 | while num != 0: 5 | alpha = math.ceil(den/num) 6 | denVals.append(alpha) 7 | num = alpha*num - den 8 | den = den*alpha 9 | return denVals 10 | 11 | def printFraction(num,den,denVals): 12 | print("{0}/{1} =".format(num,den),end=" ") 13 | for i in range(len(denVals)): 14 | if i!=len(denVals)-1: 15 | print("1/{0} +".format(denVals[i]),end=" ") 16 | else: 17 | print("1/{0}".format(denVals[i]),end=" ") 18 | 19 | num = 6 20 | den = 14 21 | denVals = egyptianFraction(num,den) 22 | printFraction(num,den,denVals) -------------------------------------------------------------------------------- /Level 2/Recursion/Generate all permutations of a string.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | 3 | class Solution: 4 | def permute(self,s,l,r): 5 | if l==r: 6 | print(''.join(s)) 7 | else: 8 | for i in range(l,r+1): 9 | s[i],s[l] = s[l],s[i] 10 | self.permute(s,l+1,r) 11 | s[i],s[l] = s[l],s[i] 12 | 13 | def permute(self,s): 14 | n = len(s) 15 | for i in itertools.permutations(s,n): 16 | print(''.join(i)) 17 | 18 | s = "aab" 19 | s = list(s) 20 | n = len(s) 21 | sol = Solution() 22 | sol.permute(s) 23 | print() 24 | #sol.permute(s,0,n-1) -------------------------------------------------------------------------------- /Level 2/Searching/Find the element that appears once in a sorted array (binary search).py: -------------------------------------------------------------------------------- 1 | def solve(arr,low,high): 2 | if low>high: 3 | return None 4 | if low==high: 5 | return arr[low] 6 | mid = (low+high)//2 7 | if mid%2==0: 8 | if arr[mid]==arr[mid+1]: 9 | return solve(arr,mid+2,high) 10 | else: 11 | return solve(arr,low,mid) 12 | else: 13 | if arr[mid]==arr[mid-1]: 14 | return solve(arr,mid+1,high) 15 | else: 16 | return solve(arr,low,mid-1) 17 | 18 | arr = [1.,1,2,4,4,5,5,6,6] 19 | ans = solve(arr,0,len(arr)-1) 20 | print(ans) -------------------------------------------------------------------------------- /Level 1/Recursion/Check if number is armstrong or not.py: -------------------------------------------------------------------------------- 1 | len = 0 2 | def lengthOfANumber(num): 3 | global len 4 | if num<10: 5 | len=len+1 6 | return 7 | len=len+1 8 | lengthOfANumber(num//10) 9 | 10 | value = 0 11 | def armstrongValue(num,len): 12 | global value 13 | if num<10: 14 | value=value+(num%10)**len 15 | return 16 | value=value+(num%10)**len 17 | armstrongValue(num//10,len) 18 | 19 | 20 | 21 | num = 1531 22 | lengthOfANumber(num) 23 | armstrongValue(num,len) 24 | 25 | if value==num: 26 | print("Armstrong number") 27 | else: 28 | print("Not a armstrong number") -------------------------------------------------------------------------------- /Level 1/Searching/Find Pivot in rotated and sorted array.py: -------------------------------------------------------------------------------- 1 | def pivot(arr,start,end): 2 | n = len(arr) 3 | res = -1 4 | while start <= end: 5 | mid = (start+end)//2 6 | prev = (mid+n-1)%n 7 | next = (mid+1)%n 8 | if arr[mid]<=arr[next] and arr[mid]<=arr[prev]: 9 | res = mid 10 | break 11 | elif arr[start] < arr[mid]: 12 | start = mid+1 13 | elif arr[end]>arr[mid]: 14 | end = mid-1 15 | return res 16 | 17 | arr = [8,11,12,15,18,2,5,6] 18 | start = 0 19 | end = len(arr)-1 20 | pivotIndex = pivot(arr,start,end) 21 | print(pivotIndex) -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Longest common subsequnce Memorized.py: -------------------------------------------------------------------------------- 1 | def lcs(x,y,n,m,dp): 2 | if n==0 or m==0: 3 | return 0 4 | if dp[n][m]!=-1: 5 | return dp[n][m] 6 | if x[n-1] == y[m-1]: 7 | dp[n][m] = 1+ lcs(x,y,n-1,m-1,dp) 8 | return dp[n][m] 9 | else: 10 | dp[n][m] = max(lcs(x,y,n-1,m,dp),lcs(x,y,n,m-1,dp)) 11 | return dp[n][m] 12 | 13 | x = "abcde" 14 | y = "ace" 15 | n = len(x) 16 | m = len(y) 17 | 18 | dp = [] 19 | for _ in range(n+1): 20 | row = [] 21 | for __ in range(m+1): 22 | row.append(-1) 23 | dp.append(row) 24 | 25 | length = lcs(x,y,n,m,dp) 26 | print(length) -------------------------------------------------------------------------------- /Level 1/Heap/Implementing Heap.py: -------------------------------------------------------------------------------- 1 | class MaxHeap: 2 | def __init__(self,items=[]): 3 | self.heap = [0] 4 | for i in items: 5 | self.heap.append(i) 6 | self.__floatUp(len(self.heap)-1) 7 | 8 | def __floatUp(self,index): 9 | parent = index//2 10 | if index<=1: 11 | return 12 | elif self.heap[index]>self.heap[parent]: 13 | self.__swap(index,parent) 14 | self.__floatUp(parent) 15 | 16 | def __swap(self,i,j): 17 | self.heap[i],self.heap[j] = self.heap[j],self.heap[i] 18 | 19 | arr = [1,96,78,2] 20 | m = MaxHeap(arr) 21 | print(m.heap) 22 | -------------------------------------------------------------------------------- /Level 2/String/Length of the longest substring without repeating characters.py: -------------------------------------------------------------------------------- 1 | def areDistinct(str,i,j): 2 | visited = [0]*26 3 | for k in range(i,j+1): 4 | if visited[ord(str[k])-ord('A')]: 5 | return False 6 | visited[ord(str[k])-ord('A')] = True 7 | return True 8 | 9 | def longestUniqueSubstring(str): 10 | n = len(str) 11 | maxLength = 0 12 | for i in range(n): 13 | for j in range(i,n): 14 | if areDistinct(str,i,j): 15 | maxLength = max(maxLength,j-i+1) 16 | return maxLength 17 | 18 | str = "ABDEFGABEF" 19 | lenStr = longestUniqueSubstring(str) 20 | print(lenStr) -------------------------------------------------------------------------------- /Level 1/Bit Manipulation/Convert decimal to decimal.py: -------------------------------------------------------------------------------- 1 | def decimalToBinary1(num): 2 | bin_num = [] 3 | while num>=1: 4 | bin_num.append(str(num%2)) 5 | num = num//2 6 | bin_num.reverse() 7 | return ''.join(bin_num) 8 | 9 | def decimalToBinary2(num,bin_num): 10 | if num>=1: 11 | decimalToBinary2(num//2,bin_num) 12 | bin_num.append(str(num%2)) 13 | 14 | 15 | dec_num = 22 16 | 17 | bin_num = decimalToBinary1(dec_num) 18 | print(bin_num) 19 | 20 | bin_num = [] 21 | decimalToBinary2(dec_num,bin_num) 22 | bin_num = ''.join(bin_num) 23 | print(bin_num) 24 | 25 | bin_num = bin(dec_num)[2:] 26 | print(bin_num) 27 | -------------------------------------------------------------------------------- /Level 1/Linked List/Delete a Linked List.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtStart(self,data): 11 | newNode = Node(data) 12 | newNode.next =self.head 13 | self.head = newNode 14 | 15 | def delete(self): 16 | cur = self.head 17 | while cur: 18 | prev = cur.next 19 | del cur.val 20 | cur = prev 21 | 22 | l = LinkedList() 23 | nodes_val = [1,2,3,4,5] 24 | for i in nodes_val: 25 | l.insertAtStart(i) 26 | 27 | -------------------------------------------------------------------------------- /Level 1/Space complexity/Code/Fibonacci Variations.py: -------------------------------------------------------------------------------- 1 | def fibonacci1(n): 2 | arr = [0, 1] 3 | for i in range(2,n): 4 | arr.append(arr[i-2] + arr[i-1]) 5 | return arr[n - 1] 6 | 7 | def fibonacci2(n): 8 | x = 0 9 | y = 1 10 | if n == 0: 11 | return x 12 | elif n == 1: 13 | return y 14 | for i in range(2,n): 15 | z = x + y 16 | x = y 17 | y = z 18 | return z 19 | 20 | def fibonacci3(n): 21 | if n==1: 22 | return 0 23 | elif n==2: 24 | return 1 25 | return fibonacci3(n-1)+fibonacci3(n-2) 26 | 27 | print(fibonacci1(5)) 28 | print(fibonacci2(5)) 29 | print(fibonacci3(5)) -------------------------------------------------------------------------------- /Level 1/Linked List/Print a Linked List.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtStart(self,data): 11 | newNode = Node(data) 12 | newNode.next =self.head 13 | self.head = newNode 14 | 15 | def print(self): 16 | cur = self.head 17 | while cur!=None: 18 | print(cur.val,end=" ") 19 | cur = cur.next 20 | print() 21 | 22 | l = LinkedList() 23 | nodes_val = [1,2,3,4,5] 24 | for i in nodes_val: 25 | l.insertAtStart(i) 26 | 27 | l.print() -------------------------------------------------------------------------------- /Level 2/Dynamic Programming/Ugly Number (optimised).py: -------------------------------------------------------------------------------- 1 | def nthUglyNum(n): 2 | ugly = [0]*n 3 | ugly[0] = 1 4 | i2 = 0 5 | i3 = 0 6 | i5 = 0 7 | next2 = 2 8 | next3 = 3 9 | next5 = 5 10 | 11 | for i in range(1,n): 12 | ugly[i] = min(next2,next3,next5) 13 | 14 | if ugly[i] == next2: 15 | i2 += 1 16 | next2 = ugly[i2]*2 17 | 18 | if ugly[i] == next5: 19 | i5 += 1 20 | next5 = ugly[i5]*5 21 | 22 | if ugly[i] == next3: 23 | i3 += 1 24 | next3 = ugly[i3]*3 25 | 26 | return ugly[n-1] 27 | 28 | n = 10 29 | num = nthUglyNum(n) 30 | print(num) -------------------------------------------------------------------------------- /Level 1/String/Check if given string has all unique characters.py: -------------------------------------------------------------------------------- 1 | def isAllUnique1(ip_str): 2 | count = {} 3 | for i in ip_str: 4 | if i not in count: 5 | count[i] = 1 6 | else: 7 | count[i] = count[i]+1 8 | 9 | for char,c in count.items(): 10 | if c!=1: 11 | return False 12 | return True 13 | 14 | 15 | ip_str = 'abcdd' 16 | flag = isAllUnique1(ip_str) 17 | print(flag) 18 | 19 | def isAllUnique2(ip_str): 20 | unique_ip_str = set(ip_str) 21 | if len(ip_str) == len(unique_ip_str): 22 | return True 23 | return False 24 | 25 | 26 | ip_str = 'abcdd' 27 | flag = isAllUnique2(ip_str) 28 | print(flag) -------------------------------------------------------------------------------- /Level 2/Array/Equilibrium Point .py: -------------------------------------------------------------------------------- 1 | def equilibrium(arr): 2 | for i in range(0,len(arr)): 3 | leftSum = 0 4 | rightSum = 0 5 | for j in range(0,i): 6 | leftSum = leftSum+arr[j] 7 | for j in range(i+1,len(arr)): 8 | rightSum = rightSum+arr[j] 9 | if leftSum == rightSum: 10 | return i 11 | return -1 12 | 13 | def equilibrium(arr): 14 | leftSum = 0 15 | rightSum = 0 16 | for i in range(len(arr)): 17 | rightSum = rightSum+arr[i] 18 | for i in range(0,len(arr)): 19 | rightSum = rightSum-arr[i] 20 | if leftSum == rightSum: 21 | return i 22 | leftSum = leftSum+arr[i] 23 | return -1 24 | 25 | arr = [-7,1,5,2,-4,3,0] 26 | point = equilibrium(arr) 27 | print(point) 28 | -------------------------------------------------------------------------------- /Level 2/Trees/Print all root to leaf paths.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__ (self,data): 3 | self.val = data 4 | self.left = None 5 | self.right = None 6 | 7 | def rootToLeaf(root,stack = []): 8 | if root==None: 9 | return 10 | stack.append(root.val) 11 | rootToLeaf(root.left) 12 | if root.left==None and root.right==None: 13 | print(*stack) 14 | rootToLeaf(root.right) 15 | stack.pop(-1) 16 | 17 | tree = Node(6) 18 | tree.left = Node(4) 19 | tree.right = Node(8) 20 | tree.left.left = Node(3) 21 | p = tree.left.right = Node(5) 22 | q = tree.right.left = Node(7) 23 | tree.right.right = Node(9) 24 | 25 | rootToLeaf(tree) -------------------------------------------------------------------------------- /Level 1/Searching/Ternary Search.py: -------------------------------------------------------------------------------- 1 | def ternarySearch(arr,ele,start,end): 2 | ind = -1 3 | while start <= end: 4 | m1 = (2*start+end)//3 5 | m2 = (start+end*2)//3 6 | if ele == arr[m1]: 7 | ind = m1 8 | break 9 | elif ele == arr[m2]: 10 | ind = m2 11 | break 12 | elif ele < arr[m1]: 13 | end = m1-1 14 | elif ele > arr[m2]: 15 | start = m2+1 16 | else: 17 | start = m1+1 18 | end = m2-1 19 | return ind 20 | 21 | 22 | 23 | arr = [1,2,5,9,14] 24 | ele = 5 25 | start = 0 26 | end = len(arr)-1 27 | index = ternarySearch(arr,ele,start,end) 28 | print(index) -------------------------------------------------------------------------------- /Level 1/Linked List/Length of Linked List iterative.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtStart(self,data): 11 | newNode = Node(data) 12 | newNode.next =self.head 13 | self.head = newNode 14 | 15 | def length(self): 16 | cur = self.head 17 | len = 0 18 | while cur!=None: 19 | len=len+1 20 | cur = cur.next 21 | return len 22 | 23 | l = LinkedList() 24 | nodes_val = [1,2,3,4,5] 25 | for i in nodes_val: 26 | l.insertAtStart(i) 27 | 28 | len = l.length() 29 | print(len) -------------------------------------------------------------------------------- /Level 1/Array/Upper, lower triangular matrix.py: -------------------------------------------------------------------------------- 1 | def upperTri(mat): 2 | tri = [] 3 | for i in range(len(mat)): 4 | row = [] 5 | for j in range(len(mat[0])): 6 | if i<=j: 7 | row.append(mat[i][j]) 8 | tri.append(row) 9 | return tri 10 | 11 | def lowerTri(mat): 12 | tri = [] 13 | for i in range(len(mat)): 14 | row = [] 15 | for j in range(len(mat[0])): 16 | if i>=j: 17 | row.append(mat[i][j]) 18 | tri.append(row) 19 | return tri 20 | 21 | mat = [ 22 | [1,2,3], 23 | [4,5,6], 24 | [7,8,9] 25 | ] 26 | 27 | tri = upperTri(mat) 28 | print(tri) 29 | 30 | tri = lowerTri(mat) 31 | print(tri) -------------------------------------------------------------------------------- /Level 1/Graph/DFS Traversal.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | class Graph: 4 | def __init__(self): 5 | self.graph = defaultdict(list) 6 | 7 | def addEdge(self,u,v): 8 | self.graph[u].append(v) 9 | self.graph[v].append(u) 10 | 11 | def DFS(self,s): 12 | visited = [False]*(max(self.graph)+1) 13 | stack = [] 14 | stack.append(s) 15 | while stack: 16 | s = stack.pop(-1) 17 | if visited[s]==False: 18 | print(s,end=" ") 19 | visited[s] = True 20 | for i in self.graph[s]: 21 | if visited[i]==False: 22 | stack.append(i) 23 | 24 | g = Graph() 25 | g.addEdge(0, 1) 26 | g.addEdge(0, 2) 27 | g.addEdge(1, 2) 28 | g.addEdge(2, 0) 29 | g.addEdge(2, 3) 30 | g.addEdge(3, 3) 31 | 32 | g.DFS(0) -------------------------------------------------------------------------------- /Level 1/Stack & Queue/Implementating stack and its operations.py: -------------------------------------------------------------------------------- 1 | class Stack: 2 | def __init__(self): 3 | self.st = [] 4 | 5 | def push(self,data): 6 | self.st.append(data) 7 | 8 | def pop(self): 9 | popEle = -1 10 | if len(self.st)>0: 11 | popEle = self.st.pop(-1) 12 | return popEle 13 | 14 | def print(self): 15 | for i in range(len(self.st)-1,-1,-1): 16 | print(self.st[i],end= " ") 17 | print() 18 | 19 | s = Stack() 20 | values = [1,2,3,4,5] 21 | for i in values: 22 | s.push(i) 23 | s.print() 24 | print(s.pop()) 25 | print(s.pop()) 26 | print(s.pop()) 27 | print(s.pop()) 28 | print(s.pop()) 29 | print(s.pop()) 30 | 31 | s.print() -------------------------------------------------------------------------------- /Level 2/Searching/Find the element that appears once in a sorted array.py: -------------------------------------------------------------------------------- 1 | def solve(arr): 2 | hash = {} 3 | n = len(arr) 4 | ans = -1 5 | for i in arr: 6 | if i in hash: 7 | hash[i]+=1 8 | else: 9 | hash[i] = 1 10 | for ele,count in hash.items(): 11 | if count==1: 12 | ans = ele 13 | break 14 | return ans 15 | 16 | def solve(arr): 17 | ans = -1 18 | n = len(arr) 19 | for i in range(0,n-1,2): 20 | if arr[i]!=arr[i+1]: 21 | ans = arr[i] 22 | break 23 | if arr[n-2]!=arr[n-1]: 24 | ans = arr[n-1] 25 | return ans 26 | 27 | def solve(arr): 28 | xor = 0 29 | n = len(arr) 30 | for i in arr: 31 | xor = xor^i 32 | return xor 33 | 34 | arr = [1,1,2,4,4,5,5,6,6] 35 | ans = solve(arr) 36 | print(ans) -------------------------------------------------------------------------------- /Level 1/Array/Merge two sorted array to form single array.py: -------------------------------------------------------------------------------- 1 | def merge(arr1,arr2): 2 | arr = [-1]*(len(arr1)+len(arr2)) #=> [-1,-1,-1,-1,-1,-1,-1,-1] 3 | i = 0 4 | j = 0 5 | k = 0 6 | while i=start and arr[mid-1] == ele: 12 | ind = mid-1 13 | break 14 | elif ele0: 20 | if n%2==1: 21 | ans = ans*x 22 | n = n-1 23 | else: 24 | x = x*x 25 | n = n//2 26 | if flag==True: 27 | ans = 1/ans 28 | return ans 29 | 30 | x = 5 31 | n = -4 32 | ans = pow1(x,n) 33 | print(ans) 34 | 35 | ans = pow2(x,n) 36 | print(ans) 37 | 38 | -------------------------------------------------------------------------------- /Level 1/Bit Manipulation/Power of Two.py: -------------------------------------------------------------------------------- 1 | import math 2 | def isPowerOfTwo1(x): 3 | if x==0: 4 | return False 5 | while x%2==0: 6 | x=x/2 7 | if x==1: 8 | return True 9 | return False 10 | 11 | x = 0 12 | flag = isPowerOfTwo1(x) 13 | print(flag) 14 | 15 | def log2(x): 16 | if x==0: 17 | return False 18 | return math.log10(x)/math.log10(2) 19 | 20 | def isPowerOfTwo2(x): 21 | if math.ceil(log2(x))==math.floor(log2(x)): 22 | return True 23 | return False 24 | 25 | x = 10 26 | flag = isPowerOfTwo2(x) 27 | print(flag) 28 | 29 | def isPowerOfTwo2(x): 30 | if x&(x-1)==0: 31 | return True 32 | return False 33 | 34 | x = 32 35 | flag = isPowerOfTwo2(x) 36 | print(flag) -------------------------------------------------------------------------------- /Level 1/Hashing/Find all symmetric pairs.py: -------------------------------------------------------------------------------- 1 | def symmetricPairs1(arr): 2 | pairs = [] 3 | for i in range(0,len(arr)): 4 | for j in range(i+1,len(arr)): 5 | alpha = arr[i][::-1] 6 | if alpha==arr[j]: 7 | pairs.append(arr[i]) 8 | return pairs 9 | 10 | arr = [[1,2],[2,3],[4,5],[3,2],[7,9],[2,1]] 11 | pairs = symmetricPairs1(arr) 12 | print(pairs) 13 | 14 | def symmetricPairs2(arr): 15 | pairs = [] 16 | hash = {} 17 | for a,b in arr: 18 | if b in hash and hash[b]==a: 19 | pairs.append([a,b]) 20 | else: 21 | hash[a]=b 22 | return pairs 23 | 24 | arr = [[1,2],[2,3],[4,5],[3,2],[7,9],[2,1]] 25 | pairs = symmetricPairs2(arr) 26 | print(pairs) 27 | 28 | -------------------------------------------------------------------------------- /Level 1/Searching/Searching in an infinite sorted array.py: -------------------------------------------------------------------------------- 1 | def searchingInInfiniteSortedArray(arr,ele): 2 | start = 0 3 | end = 1 4 | while ele > arr[end]: 5 | start = end 6 | end = end*2 7 | ind = binarySearch(arr,ele,start,end) 8 | return ind 9 | 10 | def binarySearch(arr,ele,start,end): 11 | ind = -1 12 | while start <= end: 13 | mid = (start+end)//2 14 | if ele==arr[mid]: 15 | ind = mid 16 | break 17 | elif ele0: 11 | idx = items[i][1] 12 | if wt >= weight[idx]: 13 | profit += values[idx] 14 | wt -= weight[idx] 15 | else: 16 | profit += items[i][0]*wt 17 | wt = 0 18 | else: 19 | break 20 | return profit 21 | 22 | wt = 50 23 | values = [60,100,120] 24 | weight = [10,20,30] 25 | profit = knapsack(wt,values,weight) 26 | print(profit) -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Subset sum problem.py: -------------------------------------------------------------------------------- 1 | def subsetSum(weight,wt,n): 2 | dp = [] 3 | for i in range(n+1): 4 | row = [] 5 | for j in range(wt+1): 6 | if j==0: 7 | row.append(True) 8 | elif i==0: 9 | row.append(False) 10 | else: 11 | row.append(-1) 12 | dp.append(row) 13 | 14 | for i in range(1,n+1): 15 | for j in range(1,wt+1): 16 | if weight[i-1]<=j: 17 | dp[i][j] = dp[i-1][j-weight[i-1]] or dp[i-1][j] 18 | elif weight[i-1]>j: 19 | dp[i][j] = dp[i-1][j] 20 | return dp[-1][-1] 21 | 22 | arr = [2,3,5,6,8,10] 23 | sum = 10 24 | n = len(arr) 25 | 26 | val = subsetSum(arr,sum,n) 27 | print(val) -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Fibonnaci series.py: -------------------------------------------------------------------------------- 1 | # def fibonnaci(n): 2 | # if n==1: 3 | # return 0 4 | # elif n==2: 5 | # return 1 6 | # return fibonnaci(n-1)+fibonnaci(n-2) 7 | 8 | # def fibonnaci(n,dp): 9 | # if dp[n]!=-1: 10 | # return dp[n] 11 | # if n==1: 12 | # dp[n] = 0 13 | # return dp[n] 14 | # elif n==2: 15 | # dp[n] = 1 16 | # return dp[n] 17 | # dp[n] = fibonnaci(n-1,dp)+fibonnaci(n-2,dp) 18 | # return dp[n] 19 | 20 | def fibonnaci(n): 21 | arr = [0,1] 22 | for i in range(2,n): 23 | arr.append(arr[i-1]+arr[i-2]) 24 | return arr[n-1] 25 | 26 | n = 6 27 | # dp = [] 28 | # for _ in range(n+1): 29 | # dp.append(-1) 30 | fib = fibonnaci(n) 31 | # print(dp) 32 | print(fib) -------------------------------------------------------------------------------- /Level 1/Searching/Index of first one in a binary sorted array.py: -------------------------------------------------------------------------------- 1 | def firstOccurence(arr,ele,start,end): 2 | ind = -1 3 | while start <= end: 4 | mid = (start+end)//2 5 | if ele==arr[mid]: 6 | ind = mid 7 | end = mid-1 8 | elif ele arr[end]: 19 | start = end 20 | end = end*2 21 | ind = firstOccurence(arr,ele,start,end) 22 | return ind 23 | 24 | 25 | arr = [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] 26 | ele = 1 27 | index = searchingOneInInfiniteSortedArray(arr,ele) 28 | print(index) 29 | -------------------------------------------------------------------------------- /Level 1/Stack & Queue/Parenthesis checker.py: -------------------------------------------------------------------------------- 1 | def areBracketsBalanced(exp): 2 | stack = [] 3 | for char in exp: 4 | if char in ['(','[','{']: 5 | stack.append(char) 6 | elif char in [')',']','}']: 7 | if not stack: 8 | return False 9 | alpha = stack.pop() 10 | if alpha == "(": 11 | if char != ")": 12 | return False 13 | if alpha == "[": 14 | if char != "]": 15 | return False 16 | if alpha == "{": 17 | if char != "}": 18 | return False 19 | if stack: 20 | return False 21 | return True 22 | 23 | exp = "{[()][}" 24 | flag = areBracketsBalanced(exp) 25 | print(flag) -------------------------------------------------------------------------------- /Level 1/String/Reverse a string.py: -------------------------------------------------------------------------------- 1 | #1st approach 2 | def reverse1(ip_str): 3 | op_str = '*'*len(ip_str) 4 | ip_str = list(ip_str) 5 | op_str = list(op_str) 6 | 7 | j = 0 8 | for i in range(len(ip_str)-1,-1,-1): 9 | op_str[j] = ip_str[i] 10 | j=j+1 11 | op_str = ''.join(op_str) 12 | return op_str 13 | 14 | ip_str = 'akarsh' 15 | ip_str = reverse1(ip_str) 16 | print(ip_str) 17 | 18 | 19 | #2st approach 20 | def reverse2(ip_str): 21 | ip_str = list(ip_str) 22 | i = 0 23 | j = len(ip_str)-1 24 | while ij: 19 | dp[i][j] = dp[i-1][j] 20 | return dp[-1][-1] 21 | 22 | 23 | coins = [1,2,3] 24 | sum = 5 25 | n = len(coins) 26 | 27 | val = coinChangeMax(coins,sum,n) 28 | print(val) 29 | 30 | -------------------------------------------------------------------------------- /Level 2/Array/Rearrange array alternatively in maximum and minimum form.py: -------------------------------------------------------------------------------- 1 | def rearrange(arr): 2 | n = len(arr) 3 | temp = n*[None] 4 | small = 0 5 | large = n-1 6 | flag = True 7 | for i in range(n): 8 | if flag: 9 | temp[i] = arr[large] 10 | large-=1 11 | else: 12 | temp[i] = arr[small] 13 | small+=1 14 | flag = 1-flag 15 | for i in range(n): 16 | arr[i] = temp[i] 17 | 18 | def rearrange(arr): 19 | n = len(arr) 20 | maxIdx = n-1 21 | minIdx = 0 22 | maxEle = arr[n-1]+1 23 | for i in range(n): 24 | if i%2==0: 25 | arr[i]+=(arr[maxIdx]%maxEle)*maxEle 26 | maxIdx-=1 27 | else: 28 | arr[i]+=(arr[minIdx]%maxEle)*maxEle 29 | minIdx+=1 30 | for i in range(n): 31 | arr[i] = arr[i]//maxEle 32 | 33 | arr = [1,2,3,4,5,6] 34 | rearrange(arr) 35 | print(arr) -------------------------------------------------------------------------------- /Level 2/Searching/How many times a sorted array is rotated.py: -------------------------------------------------------------------------------- 1 | def pivot(arr,start,end): 2 | n = len(arr) 3 | res = -1 4 | while start <= end: 5 | mid = (start+end)//2 6 | prev = (mid+n-1)%n 7 | next = (mid+1)%n 8 | if arr[mid]<=arr[next] and arr[mid]<=arr[prev]: 9 | res = mid 10 | break 11 | elif arr[start] < arr[mid]: 12 | start = mid+1 13 | elif arr[end]>arr[mid]: 14 | end = mid-1 15 | return res 16 | 17 | def timesRotated(arr): 18 | start = 0 19 | end = len(arr)-1 20 | pivotIndex = pivot(arr,start,end) 21 | #print(pivotIndex) 22 | times = len(arr)-pivotIndex 23 | return times 24 | 25 | arr = [8,11,12,15,18,2,5,6] 26 | times = timesRotated(arr) 27 | print(times) 28 | -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Longest common subsequnce Tabular.py: -------------------------------------------------------------------------------- 1 | def lcs(x,y,n,m): 2 | dp = [] 3 | for i in range(n+1): 4 | row = [] 5 | for j in range(m+1): 6 | if i==0 or j==0: 7 | row.append(0) 8 | else: 9 | row.append(-1) 10 | dp.append(row) 11 | 12 | for i in dp: 13 | print(*i) 14 | 15 | for i in range(1,n+1): 16 | for j in range(1,m+1): 17 | if x[i-1] == y[j-1]: 18 | dp[i][j] = 1+dp[i-1][j-1] 19 | else: 20 | dp[i][j] = max(dp[i][j-1],dp[i-1][j]) 21 | 22 | for i in dp: 23 | print(*i) 24 | 25 | return dp[-1][-1] 26 | 27 | x = "abcde" 28 | y = "ace" 29 | n = len(x) 30 | m = len(y) 31 | length = lcs(x,y,n,m) 32 | print(length) -------------------------------------------------------------------------------- /Level 1/String/Check if a string is substring of another or not.py: -------------------------------------------------------------------------------- 1 | def isSubstring1(s1,s2): 2 | m = len(s1) 3 | n = len(s2) 4 | for i in range(n-m+1): 5 | for j in range(m): 6 | if s2[i+j]!=s1[j]: 7 | break 8 | if j+1==m: 9 | return i 10 | return -1 11 | 12 | s1 = "euro" 13 | s2 = "ineuron" 14 | flag = isSubstring1(s1,s2) 15 | print(flag) 16 | 17 | def isSubstring2(s1,s2): 18 | t = 0 19 | l = len(s1) 20 | i = 0 21 | for i in range(l): 22 | if t==len(s2): 23 | break 24 | if s1[i]==s2[t]: 25 | t+=1 26 | else: 27 | t = 0 28 | if t1 and str[0]==str[1]: 7 | str = str[1:] 8 | str = str[1:] 9 | return remove(str,lastRemoved) 10 | rem = remove(str[1:],lastRemoved) 11 | if len(rem)!=0 and rem[0]==str[0]: 12 | lastRemoved = str[0] 13 | return rem[1:] 14 | if len(rem)==0 and lastRemoved == str[0]: 15 | return rem 16 | return ([str[0]]+rem) 17 | 18 | def removeAdjacentDuplicates(str): 19 | lastRemoved = 0 20 | return ''.join(remove(list(str),lastRemoved)) 21 | 22 | str = "azxxzy" 23 | str = removeAdjacentDuplicates(str) 24 | print(str) -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Count subsets with given sum.py: -------------------------------------------------------------------------------- 1 | def subsetsWithGivenSum(weight,wt,n): 2 | dp = [] 3 | for i in range(n+1): 4 | row = [] 5 | for j in range(wt+1): 6 | if j==0: 7 | row.append(1) 8 | elif i==0: 9 | row.append(0) 10 | else: 11 | row.append(-1) 12 | dp.append(row) 13 | 14 | for i in range(1,n+1): 15 | for j in range(1,wt+1): 16 | if weight[i-1]<=j: 17 | dp[i][j] = dp[i-1][j-weight[i-1]] + dp[i-1][j] 18 | elif weight[i-1]>j: 19 | dp[i][j] = dp[i-1][j] 20 | return dp[-1][-1] 21 | 22 | arr = [2,3,5,6,8,10] 23 | sum = 100 24 | n = len(arr) 25 | 26 | count = subsetsWithGivenSum(arr,sum,n) 27 | print(count) 28 | 29 | 30 | -------------------------------------------------------------------------------- /Level 1/Linked List/Search in a Linked List.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtStart(self,data): 11 | newNode = Node(data) 12 | newNode.next =self.head 13 | self.head = newNode 14 | 15 | def search(self,key): 16 | cur = self.head 17 | keyNode = None 18 | while cur!=None: 19 | if cur.val == key: 20 | keyNode = cur 21 | break 22 | cur=cur.next 23 | return keyNode 24 | 25 | l = LinkedList() 26 | nodes_val = [1,2,3,4,5] 27 | for i in nodes_val: 28 | l.insertAtStart(i) 29 | 30 | key = 3 31 | keyNode = l.search(key) 32 | print(keyNode.val) -------------------------------------------------------------------------------- /Level 1/String/Check if given string is pallindrome or not.py: -------------------------------------------------------------------------------- 1 | def reverse(ip_str): 2 | ip_str = list(ip_str) 3 | i = 0 4 | j = len(ip_str)-1 5 | while iarr[i]: 26 | return False 27 | return True 28 | 29 | arr = [1,2,5,100,7,8] 30 | flag = sortedOrNot3(arr) 31 | print(flag) -------------------------------------------------------------------------------- /Level 1/Array/Transpose of a Matrix.py: -------------------------------------------------------------------------------- 1 | def transpose1(mat): 2 | l = [] 3 | for i in range(len(mat)): 4 | row = [] 5 | for j in range(len(mat[0])): 6 | row.append(-1) 7 | l.append(row) 8 | 9 | for i in range(len(mat)): 10 | for j in range(len(mat[0])): 11 | l[i][j] = mat[j][i] 12 | 13 | return l 14 | 15 | mat = [ 16 | [1,2,3], 17 | [4,5,6], 18 | [7,8,9] 19 | ] 20 | 21 | l = transpose1(mat) 22 | print(l) 23 | 24 | def transpose2(mat): 25 | for i in range(len(mat)): 26 | for j in range(len(mat[0])): 27 | if i>j: 28 | mat[i][j],mat[j][i] = mat[j][i],mat[i][j] 29 | 30 | mat = [ 31 | [1,2,3], 32 | [4,5,6], 33 | [7,8,9] 34 | ] 35 | 36 | transpose2(mat) 37 | print(mat) -------------------------------------------------------------------------------- /Level 1/Linked List/Insertion Singly Linked List at end.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | l = LinkedList() 28 | nodes_val = [1,2,3,4,5] 29 | for val in nodes_val: 30 | l.insertAtEnd(val) 31 | l.print() -------------------------------------------------------------------------------- /Level 2/Maths/Sieve of Eratosthenes.py: -------------------------------------------------------------------------------- 1 | import math 2 | def isPrime(n): 3 | if n<=1: 4 | return False 5 | for i in range(2,int(math.sqrt(n))+1): 6 | if n%i==0: 7 | return False 8 | return True 9 | 10 | def primeRange(n): 11 | ans = [] 12 | for i in range(1,n+1): 13 | if isPrime(i): 14 | ans.append(i) 15 | return ans 16 | 17 | n = 20 18 | primeNums = primeRange(n) 19 | print(primeNums) 20 | 21 | 22 | def sieveOfEratosthenes(n): 23 | prime = [True for i in range(n+1)] 24 | prime[0],prime[1] = False, False 25 | ans = [] 26 | p = 2 27 | while p*p <=n: 28 | if prime[p] == True: 29 | for i in range(p*p,n+1,p): 30 | prime[i] = False 31 | 32 | p+=1 33 | 34 | for i in range(1,n+1): 35 | if prime[i]: 36 | ans.append(i) 37 | return ans 38 | 39 | n = 20 40 | primeNums = sieveOfEratosthenes(n) 41 | print(primeNums) -------------------------------------------------------------------------------- /Level 2/Array/Count the triplets.py: -------------------------------------------------------------------------------- 1 | def twoSum2(arr,sum): 2 | low = 0 3 | high = len(arr)-1 4 | arr.sort() 5 | while lowsum: 9 | high-=1 10 | else: 11 | low = low+1 12 | return False 13 | 14 | def tripletSum(arr): 15 | n = len(arr) 16 | for i in range(0,n): 17 | for j in range(i+1,n): 18 | for k in range(0,n): 19 | if i!=j!=k and arr[i] == arr[j]+arr[k]: 20 | print(arr[i],arr[j],arr[k]) 21 | 22 | def tripletSum(arr): 23 | n = len(arr) 24 | arr.sort(reverse = True) 25 | for i in range(0,n): 26 | if twoSum2(arr[i+1:n],arr[i]) == True: 27 | return True 28 | return False 29 | 30 | arr =[5,32,1,7,10,50,19,21,2] 31 | count = tripletSum(arr) 32 | print(count) -------------------------------------------------------------------------------- /Level 1/Maths/Factors of a number.py: -------------------------------------------------------------------------------- 1 | import math 2 | def factors1(n): 3 | factors_list = [] 4 | i = 1 5 | while i<=n: 6 | if n%i==0: 7 | factors_list.append(i) 8 | i=i+1 9 | return factors_list 10 | 11 | 12 | n = 18 13 | factors_list = factors1(n) 14 | print(factors_list) 15 | 16 | def factors2(n): 17 | factors_list1 = [] 18 | factors_list2 = [] 19 | i = 1 20 | while i<=math.sqrt(n): 21 | if n%i==0: 22 | if n/i==i: 23 | factors_list1.append(i) 24 | else: 25 | factors_list1.append(i) 26 | factors_list2.append(n//i) 27 | i=i+1 28 | factors_list2.reverse() 29 | factors_list1.extend(factors_list2) 30 | return factors_list1 31 | 32 | 33 | n = 100 34 | factors_list = factors2(n) 35 | print(factors_list) -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Shortest common supersequence.py: -------------------------------------------------------------------------------- 1 | def lcs(x,y,n,m): 2 | dp = [] 3 | for i in range(n+1): 4 | row = [] 5 | for j in range(m+1): 6 | if i==0 or j==0: 7 | row.append(0) 8 | else: 9 | row.append(-1) 10 | dp.append(row) 11 | 12 | # for i in dp: 13 | # print(*i) 14 | 15 | for i in range(1,n+1): 16 | for j in range(1,m+1): 17 | if x[i-1] == y[j-1]: 18 | dp[i][j] = 1+dp[i-1][j-1] 19 | else: 20 | dp[i][j] = max(dp[i][j-1],dp[i-1][j]) 21 | 22 | # for i in dp: 23 | # print(*i) 24 | 25 | return dp[-1][-1] 26 | 27 | def scs(x,y,n,m): 28 | return m+n - lcs(x,y,n,m) 29 | 30 | x = "geek" 31 | y = "eke" 32 | n = len(x) 33 | m = len(y) 34 | length = scs(x,y,n,m) 35 | print(length) -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/0-1 Knapsack Memorized.py: -------------------------------------------------------------------------------- 1 | def knapsack(weight,value,wt,n,dp): 2 | if n==0 or wt==0: 3 | return 0 4 | if dp[n][wt]!=-1: 5 | return dp[n][wt] 6 | if weight[n-1]<=wt: 7 | dp[n][wt] = max( 8 | value[n-1]+ 9 | knapsack(weight,value,wt-weight[n-1],n-1,dp), 10 | knapsack(weight,value,wt,n-1,dp) 11 | ) 12 | return dp[n][wt] 13 | elif weight[n-1]>wt: 14 | dp[n][wt] = knapsack(weight,value,wt,n-1,dp) 15 | return dp[n][wt] 16 | 17 | weight = [1,3,4,5] 18 | value = [1,4,5,7] 19 | wt = 7 20 | n = len(weight) 21 | 22 | dp = [] 23 | for _ in range(n+1): 24 | row = [] 25 | for __ in range(wt+1): 26 | row.append(-1) 27 | dp.append(row) 28 | 29 | val = knapsack(weight,value,wt,n,dp) 30 | print(dp) 31 | print(val) 32 | -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Longest common substring O(n^2).py: -------------------------------------------------------------------------------- 1 | import sys 2 | def lcs(x,y,n,m): 3 | dp = [] 4 | for i in range(n+1): 5 | row = [] 6 | for j in range(m+1): 7 | if i==0 or j==0: 8 | row.append(0) 9 | else: 10 | row.append(-1) 11 | dp.append(row) 12 | 13 | for i in dp: 14 | print(*i) 15 | print() 16 | 17 | for i in range(1,n+1): 18 | for j in range(1,m+1): 19 | if x[i-1] == y[j-1]: 20 | dp[i][j] = 1+dp[i-1][j-1] 21 | else: 22 | dp[i][j] = 0 23 | max = -sys.maxsize 24 | for i in dp: 25 | for j in i: 26 | if j>max: 27 | max = j 28 | 29 | return max 30 | 31 | x = "abcde" 32 | y = "abfce" 33 | n = len(x) 34 | m = len(y) 35 | length = lcs(x,y,n,m) 36 | print(length) -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Coin change min ways.py: -------------------------------------------------------------------------------- 1 | import sys 2 | def coinChangeMin(coins,sum,n): 3 | dp = [] 4 | for i in range(n+1): 5 | row = [] 6 | for j in range(sum+1): 7 | if j==0: 8 | row.append(0) 9 | elif i==0: 10 | row.append(sys.maxsize) 11 | else: 12 | row.append(-1) 13 | dp.append(row) 14 | 15 | for i in range(1,n+1): 16 | for j in range(1,sum+1): 17 | if coins[i-1]<=j: 18 | dp[i][j] = min( 19 | 1+dp[i][j-coins[i-1]], 20 | dp[i-1][j] 21 | ) 22 | elif coins[i-1]>j: 23 | dp[i][j] = dp[i-1][j] 24 | return dp[-1][-1] 25 | 26 | 27 | coins = [1,2,3] 28 | sum = 5 29 | n = len(coins) 30 | 31 | val = coinChangeMin(coins,sum,n) 32 | print(val) 33 | 34 | -------------------------------------------------------------------------------- /Level 1/Maths/Trailing zeroes in a factorial.py: -------------------------------------------------------------------------------- 1 | def trailingZeroes1(n): 2 | fact = 1 3 | for i in range(1,n+1): 4 | fact = fact*i 5 | print(fact) 6 | count = 0 7 | while 1: 8 | rem = fact%10 9 | if rem!=0: 10 | break 11 | fact = fact//10 12 | count=count+1 13 | return count 14 | 15 | n = 5 16 | zeroes = trailingZeroes1(n) 17 | print(zeroes) 18 | 19 | def trailingZeroes2(n): 20 | count2 = 0 21 | count5 = 0 22 | for i in range(1,n+1): 23 | f = i 24 | while i%2==0: 25 | count2+=1 26 | i = i//2 27 | while f%5==0: 28 | count5+=1 29 | f = f//5 30 | return min(count2,count5) 31 | 32 | n = 100 33 | zeroes = trailingZeroes2(n) 34 | print(zeroes) 35 | 36 | def trailingZeroes3(n): 37 | if n<0: 38 | return -1 39 | count = 0 40 | while n>=5: 41 | n//=5 42 | count+=n 43 | return count 44 | 45 | n = 100 46 | zeroes = trailingZeroes3(n) 47 | print(zeroes) 48 | 49 | -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/0-1 Knapsack Tabular.py: -------------------------------------------------------------------------------- 1 | def knapsack(weight,value,wt,n): 2 | dp = [] 3 | for i in range(n+1): 4 | row = [] 5 | for j in range(wt+1): 6 | if i==0 or j==0: 7 | row.append(0) 8 | else: 9 | row.append(-1) 10 | dp.append(row) 11 | 12 | for i in range(n+1): 13 | for j in range(wt+1): 14 | if weight[i-1]<=j: 15 | dp[i][j] = max( 16 | value[i-1]+dp[i-1][j-weight[i-1]], 17 | dp[i-1][j] 18 | ) 19 | elif weight[i-1]>j: 20 | dp[i][j] = dp[i-1][j] 21 | 22 | for i in dp: 23 | print(*i) 24 | 25 | return dp[-1][-1] 26 | 27 | 28 | weight = [1,3,4,5] 29 | value = [1,4,5,7] 30 | wt = 7 31 | n = len(weight) 32 | 33 | val = knapsack(weight,value,wt,n) 34 | print(val) 35 | -------------------------------------------------------------------------------- /Level 1/Linked List/Doubly Linked List/Insertion doubly Linked List at start.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | self.prev = None 6 | 7 | class LinkedList: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def insertAtStart(self,data): 12 | newNode = Node(data) 13 | if self.head==None: 14 | self.head = newNode 15 | else: 16 | self.head.prev = newNode 17 | newNode.next = self.head 18 | self.head = newNode 19 | 20 | def print(self): 21 | cur = self.head 22 | while cur!=None: 23 | print(cur.val,end=" ") 24 | cur = cur.next 25 | print() 26 | 27 | l = LinkedList() 28 | nodes_val = [1,2,3,4,5] 29 | for i in nodes_val: 30 | l.insertAtStart(i) 31 | 32 | print(l.head.val) 33 | l.print() -------------------------------------------------------------------------------- /Level 1/Linked List/Loop in linked list using tortoise and hare algorithm.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def checkLoop(self): 11 | loopNode = None 12 | slow = self.head 13 | fast = self.head 14 | while slow and fast and fast.next: 15 | slow = slow.next 16 | fast = fast.next.next 17 | if slow==fast: 18 | loopNode = slow 19 | break 20 | return loopNode 21 | 22 | 23 | l = LinkedList() 24 | l.head = Node(5) 25 | l.head.next = Node(1) 26 | l.head.next.next = Node(6) 27 | p = l.head.next.next 28 | l.head.next.next.next = Node(7) 29 | l.head.next.next.next.next = Node(8) 30 | 31 | loopNode = l.checkLoop() 32 | print(loopNode.val) 33 | -------------------------------------------------------------------------------- /Level 1/Stack & Queue/Implementing Stack using linked list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class Stack: 7 | def __init__(self): 8 | self.top = None 9 | 10 | def push(self,data): 11 | newNode = Node(data) 12 | newNode.next = self.top 13 | self.top = newNode 14 | 15 | def pop(self): 16 | if self.top == None: 17 | return None 18 | else: 19 | popNode = self.top 20 | self.top = self.top.next 21 | return popNode 22 | 23 | def print(self): 24 | t = self.top 25 | while t!=None: 26 | print(t.val,end=" ") 27 | t = t.next 28 | print() 29 | 30 | s = Stack() 31 | nodes_val = [1,2,3,4,5] 32 | for i in nodes_val: 33 | s.push(i) 34 | s.print() 35 | print(s.pop().val) 36 | s.print() -------------------------------------------------------------------------------- /Level 1/Linked List/Deletion Singly Linked List from start.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtStart(self,data): 11 | newNode = Node(data) 12 | newNode.next =self.head 13 | self.head = newNode 14 | 15 | def deleteAtStart(self): 16 | if self.head==None: 17 | return None 18 | else: 19 | self.head = self.head.next 20 | 21 | def print(self): 22 | cur = self.head 23 | while cur!=None: 24 | print(cur.val,end=" ") 25 | cur = cur.next 26 | print() 27 | 28 | l = LinkedList() 29 | nodes_val = [1,2,3,4,5] 30 | for i in nodes_val: 31 | l.insertAtStart(i) 32 | 33 | l.print() #=> 5,4,3,2,1 34 | l.deleteAtStart() 35 | l.print() #=> 4,3,2,1 -------------------------------------------------------------------------------- /Level 1/Linked List/Loop in linked list using hashing.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def checkLoop(self): 11 | hash = {} 12 | loopNode = None 13 | cur = self.head 14 | while cur!=None: 15 | if cur not in hash: 16 | hash[cur] = True 17 | else: 18 | loopNode = cur 19 | break 20 | cur=cur.next 21 | return loopNode 22 | 23 | 24 | l = LinkedList() 25 | l.head = Node(5) 26 | l.head.next = Node(1) 27 | l.head.next.next = Node(6) 28 | p = l.head.next.next 29 | l.head.next.next.next = Node(7) 30 | l.head.next.next.next.next = Node(8) 31 | l.head.next.next.next.next.next = p 32 | 33 | loopNode = l.checkLoop() 34 | print(loopNode) 35 | -------------------------------------------------------------------------------- /Level 1/String/Print duplicate characters of given string.py: -------------------------------------------------------------------------------- 1 | def duplicateChar1(ip_str): 2 | count = [] 3 | for i in list(set(ip_str)): 4 | c = 0 5 | for j in ip_str: 6 | if i==j: 7 | c+=1 8 | count.append([i,c]) 9 | 10 | ans = [] 11 | for char,c in count: 12 | if c>1: 13 | ans.append(char) 14 | return ans 15 | 16 | ip_str = 'abcabaaa' 17 | duplicateList = duplicateChar1(ip_str) 18 | print(duplicateList) 19 | 20 | 21 | def duplicateChar2(ip_str): 22 | count = {} 23 | for i in ip_str: 24 | if i in count: 25 | count[i]=count[i]+1 26 | else: 27 | count[i] = 1 28 | ans = [] 29 | for char,c in count.items(): 30 | if c>1: 31 | ans.append(char) 32 | return ans 33 | 34 | ip_str = 'abcabaaa' 35 | duplicateList = duplicateChar2(ip_str) 36 | print(duplicateList) -------------------------------------------------------------------------------- /Level 1/Stack & Queue/Next greater to right.py: -------------------------------------------------------------------------------- 1 | def solve(arr): 2 | op = [] 3 | for i in range(len(arr)): 4 | alpha = -1 5 | for j in range(i+1,len(arr)): 6 | if arr[j]>arr[i]: 7 | alpha = arr[j] 8 | break 9 | op.append(alpha) 10 | return op 11 | 12 | def solve(arr): 13 | op = [] 14 | stack = [] 15 | for i in range(len(arr)-1,-1,-1): 16 | if len(stack)==0: 17 | op.append(-1) 18 | elif stack[-1]>arr[i]: 19 | op.append(stack[-1]) 20 | else: 21 | while len(stack)>0 and stack[-1]0 and stack[-1]>arr[i]: 22 | stack.pop(-1) 23 | if len(stack)==0: 24 | op.append(-1) 25 | else: 26 | op.append(stack[-1]) 27 | stack.append(arr[i]) 28 | op.reverse() 29 | return op 30 | 31 | arr = [1,3,2,4] 32 | op = solve(arr) 33 | print(op) -------------------------------------------------------------------------------- /Level 1/Linked List/Doubly Linked List/Insertion doubly Linked List at end.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | self.prev = None 6 | 7 | class LinkedList: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def insertAtEnd(self,data): 12 | cur = self.head 13 | newNode = Node(data) 14 | if self.head==None: 15 | self.head = newNode 16 | else: 17 | while cur.next!=None: 18 | cur = cur.next 19 | cur.next = newNode 20 | newNode.prev = cur 21 | 22 | def print(self): 23 | cur = self.head 24 | while cur!=None: 25 | print(cur.val,end=" ") 26 | cur = cur.next 27 | print() 28 | 29 | l = LinkedList() 30 | nodes_val = [1,2,3,4,5] 31 | for i in nodes_val: 32 | l.insertAtEnd(i) 33 | 34 | l.print() -------------------------------------------------------------------------------- /Level 1/Graph/BFS Traversal for disconnected graph.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | class Graph: 4 | def __init__(self): 5 | self.graph = defaultdict(list) 6 | 7 | def addEdge(self,u,v): 8 | self.graph[u].append(v) 9 | self.graph[v].append(u) 10 | 11 | def BFS(self,s,visited): 12 | queue = [] 13 | queue.append(s) 14 | visited[s]= True 15 | while len(queue)!=0: 16 | s = queue.pop(0) 17 | print(s,end=" ") 18 | for i in self.graph[s]: 19 | if visited[i]==False: 20 | queue.append(i) 21 | visited[i] = True 22 | 23 | def BFS_disconnected(self): 24 | visited = [False]*(max(self.graph)+1) 25 | for i in self.graph.keys(): 26 | if not visited[i]: 27 | self.BFS(i,visited) 28 | 29 | 30 | 31 | 32 | g = Graph() 33 | g.addEdge(0, 1) 34 | g.addEdge(0, 2) 35 | g.addEdge(1, 2) 36 | g.addEdge(2, 0) 37 | g.addEdge(2, 3) 38 | g.addEdge(3, 3) 39 | g.addEdge(4,5) 40 | g.addEdge(6,7) 41 | g.BFS_disconnected() -------------------------------------------------------------------------------- /Level 1/Sorting/Merge Sort.py: -------------------------------------------------------------------------------- 1 | def merge(arr,first,middle,last): 2 | arr1 = arr[first:middle+1] 3 | arr2 = arr[middle+1:last+1] 4 | i = 0 5 | j = 0 6 | k = first 7 | 8 | while i Inplace 3 | 4 | def sort012(arr): 5 | count0 = 0 6 | count1 = 0 7 | for i in arr: 8 | if i==0: 9 | count0=count0+1 10 | elif i==1: 11 | count1=count1+1 12 | for i in range(0,count0): 13 | arr[i] = 0 14 | for i in range(count0,count1+count0): 15 | arr[i] = 1 16 | for i in range(count1+count0,len(arr)): 17 | arr[i] = 2 18 | 19 | 20 | def sort012(arr): 21 | lo = 0 22 | hi = len(arr)-1 23 | mid = 0 24 | while mid<=hi: 25 | if arr[mid]==0: 26 | arr[lo],arr[mid] = arr[mid],arr[lo] 27 | lo+=1 28 | mid+=1 29 | elif arr[mid]==1: 30 | mid=mid+1 31 | else: 32 | arr[mid],arr[hi] = arr[hi],arr[mid] 33 | hi = hi-1 34 | return arr 35 | 36 | arr = [1,1,2,2,1,0,2,1,1,0,2,0,1,1] 37 | sort012(arr) 38 | print(arr) -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Equal sum partition problem.py: -------------------------------------------------------------------------------- 1 | def subsetSum(weight,wt,n): 2 | dp = [] 3 | for i in range(n+1): 4 | row = [] 5 | for j in range(wt+1): 6 | if j==0: 7 | row.append(True) 8 | elif i==0: 9 | row.append(False) 10 | else: 11 | row.append(-1) 12 | dp.append(row) 13 | 14 | for i in range(1,n+1): 15 | for j in range(1,wt+1): 16 | if weight[i-1]<=j: 17 | dp[i][j] = dp[i-1][j-weight[i-1]] or dp[i-1][j] 18 | elif weight[i-1]>j: 19 | dp[i][j] = dp[i-1][j] 20 | 21 | # for i in dp: 22 | # print(*i) 23 | 24 | return dp[-1][-1] 25 | 26 | def equalSumPart(arr): 27 | if sum(arr)%2!=0: 28 | return False 29 | wt = sum(arr)//2 30 | n = len(arr) 31 | return subsetSum(arr,wt,n) 32 | 33 | 34 | arr = [2,3,7,8,10,2] 35 | flag = equalSumPart(arr) 36 | print(flag) -------------------------------------------------------------------------------- /Level 2/Recursion/Generate all unique permutations of a string.py: -------------------------------------------------------------------------------- 1 | def permute(s,l,r,per): 2 | if l==r: 3 | per.append(''.join(s)) 4 | else: 5 | for i in range(l,r+1): 6 | s[i],s[l] = s[l],s[i] 7 | permute(s,l+1,r,per) 8 | s[i],s[l] = s[l],s[i] 9 | 10 | def uniquePermute1(s,l,r): 11 | per = [] 12 | permute(s,l,r,per) 13 | print(list(set(per))) 14 | 15 | def check(s,l,cur): 16 | for j in range(l,cur): 17 | if s[j] == s[cur]: 18 | return False 19 | return True 20 | 21 | def uniquePermute2(s,l,r): 22 | if l==r: 23 | print(''.join(s)) 24 | else: 25 | for i in range(l,r+1): 26 | flag = check(s,l,i) 27 | if flag: 28 | s[i],s[l] = s[l],s[i] 29 | uniquePermute2(s,l+1,r) 30 | s[i],s[l] = s[l],s[i] 31 | 32 | s = "aab" 33 | s = list(s) 34 | n = len(s) 35 | uniquePermute1(s,0,n-1) 36 | uniquePermute2(s,0,n-1) -------------------------------------------------------------------------------- /Level 1/Array/Move all 0s to end of the array.py: -------------------------------------------------------------------------------- 1 | def zeroesToEnd1(arr): 2 | i = 0 3 | j = len(arr)-1 4 | while iarr[mid]: 11 | res = arr[mid] 12 | start = mid+1 13 | return res 14 | 15 | def ceil(arr,ele,start,end): 16 | res = -1 17 | while start <= end: 18 | mid = (start+end)//2 19 | if ele==arr[mid]: 20 | res = ele 21 | break 22 | elif ele>arr[mid]: 23 | start = mid+1 24 | elif ele1: 28 | nodes = sorted(nodes,key=lambda x:x.freq) 29 | left = nodes.pop(0) 30 | right = nodes.pop(0) 31 | left.huff = '0' 32 | right.huff = '1' 33 | newNode = Node( 34 | left.freq+right.freq, 35 | left.symbol+right.symbol, 36 | left, 37 | right 38 | ) 39 | nodes.append(newNode) 40 | printNodes(nodes[0]) -------------------------------------------------------------------------------- /Level 2/Array/Subarray with given sum (positive and negative elements).py: -------------------------------------------------------------------------------- 1 | def subArraySum(arr,sum): 2 | n = len(arr) 3 | for i in range(n): 4 | curSum = arr[i] 5 | for j in range(i+1,len(arr)): 6 | if sum==curSum: 7 | ans = str(i)+"->"+str(j-1) 8 | print(ans) 9 | return True 10 | curSum = curSum+arr[j] 11 | return False 12 | 13 | def subArraySum(arr,sum): 14 | n = len(arr) 15 | map = {} 16 | curSum = 0 17 | for i in range(n): 18 | curSum = curSum+arr[i] 19 | if sum==curSum: 20 | ans = str(0)+"->"+str(i) 21 | print(ans) 22 | return True 23 | if curSum-sum in map: 24 | ans = str(map[curSum-sum]+1)+"->"+str(i) 25 | print(ans) 26 | return True 27 | map[curSum] = i 28 | return False 29 | 30 | arr = [10,2,-2,-20,10] 31 | sum = -10 32 | isSumFound = subArraySum(arr,sum) 33 | print(isSumFound) -------------------------------------------------------------------------------- /Level 1/Linked List/Length of a linked list recursive.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def length(self,head): 28 | if head==None: 29 | return 0 30 | return 1+self.length(head.next) 31 | 32 | l = LinkedList() 33 | nodes_val = [1,2,3,4,5] 34 | for val in nodes_val: 35 | l.insertAtEnd(val) 36 | l.print() 37 | len = l.length(l.head) 38 | print(len) -------------------------------------------------------------------------------- /Level 1/String/Find maximum ocurring charater in given string.py: -------------------------------------------------------------------------------- 1 | import sys 2 | def maxOccurChar1(ip_str): 3 | count = [] 4 | for i in list(set(ip_str)): 5 | c = 0 6 | for j in ip_str: 7 | if i==j: 8 | c=c+1 9 | count.append([i,c]) 10 | 11 | max = -sys.maxsize 12 | ans = '' 13 | for char,cou in count: 14 | if cou>max: 15 | max = cou 16 | ans = char 17 | return ans 18 | 19 | ip_str = 'abcabacaa' 20 | op_chr = maxOccurChar1(ip_str) 21 | print(op_chr) 22 | 23 | def maxOccurChar2(ip_str): 24 | count = {} 25 | for i in ip_str: 26 | if i in count: 27 | count[i]=count[i]+1 28 | else: 29 | count[i]=1 30 | 31 | max = -sys.maxsize 32 | ans = '' 33 | for char,cou in count.items(): 34 | if cou>max: 35 | max = cou 36 | ans = char 37 | return ans 38 | 39 | ip_str = 'abcabacaa' 40 | op_chr = maxOccurChar2(ip_str) 41 | print(op_chr) -------------------------------------------------------------------------------- /Level 2/Array/Pythagorean Triplet in an array.py: -------------------------------------------------------------------------------- 1 | def twoSum2(arr,sum): 2 | low = 0 3 | high = len(arr)-1 4 | arr.sort() 5 | while lowsum: 9 | high-=1 10 | else: 11 | low = low+1 12 | return False 13 | 14 | def pythagoreanTriplet(arr): 15 | n = len(arr) 16 | for i in range(0,n-2): 17 | for j in range(i+1,n-1): 18 | for k in range(j+1,n): 19 | if arr[i]*arr[i]+arr[j]*arr[j]==arr[k]*arr[k]: 20 | print(arr[i],arr[j],arr[k]) 21 | return True 22 | return False 23 | 24 | def pythagoreanTriplet(arr): 25 | n = len(arr) 26 | for i in range(len(arr)): 27 | arr[i] = arr[i]*arr[i] 28 | arr.sort(reverse=True) 29 | print(arr) 30 | for i in range(0,n): 31 | if twoSum2(arr[i+1:n],arr[i]) == True: 32 | return True 33 | return False 34 | 35 | arr = [3,1,4,6,5] 36 | flag = pythagoreanTriplet(arr) 37 | print(flag) -------------------------------------------------------------------------------- /Level 1/Linked List/Circular Linked List/Insertion Circular Linked List from end.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.last = None 9 | 10 | def insertAtEnd(self,data): 11 | newNode = Node(data) 12 | if self.last==None: 13 | self.last = newNode 14 | newNode.next = self.last 15 | else: 16 | newNode.next = self.last.next 17 | self.last.next = newNode 18 | self.last = newNode 19 | 20 | def print(self): 21 | if self.last==None: 22 | return None 23 | cur = self.last.next 24 | 25 | while 1: 26 | print(cur.val,end=" ") 27 | if cur==self.last: 28 | break 29 | cur = cur.next 30 | print() 31 | 32 | l = LinkedList() 33 | nodes_val = [1,2,3,4,5] 34 | for i in nodes_val: 35 | l.insertAtEnd(i) 36 | l.print() -------------------------------------------------------------------------------- /Level 2/Stack and Queue/Infix to Postfix Conversion.py: -------------------------------------------------------------------------------- 1 | def infixToPostfix(infixExp): 2 | postfixExp = [] 3 | stack = [] 4 | precedence = { 5 | '+':1, 6 | '-':1, 7 | '*':2, 8 | '/':2, 9 | '^':3, 10 | '(':0, 11 | ')':4 12 | } 13 | 14 | for i in infixExp: 15 | if i.isalpha(): 16 | postfixExp.append(i) 17 | elif i=='(': 18 | stack.append(i) 19 | elif i==')': 20 | while len(stack)!=0 and stack[-1]!='(': 21 | a = stack.pop(-1) 22 | postfixExp.append(a) 23 | stack.pop(-1) 24 | else: 25 | while len(stack)!=0 and precedence[i]maxEle: 36 | # maxEle = i 37 | # return maxEle 38 | 39 | arr = [9,6,1,2,5,4,8] 40 | minEle = min(arr) 41 | print(minEle) 42 | maxEle = max(arr) 43 | print(maxEle) -------------------------------------------------------------------------------- /Level 2/Array/Subarray with given sum (positive numbers).py: -------------------------------------------------------------------------------- 1 | def subArraySum(arr,sum): 2 | n = len(arr) 3 | for i in range(n): 4 | curSum = arr[i] 5 | for j in range(i+1,len(arr)): 6 | if sum==curSum: 7 | ans = str(i)+"->"+str(j-1) 8 | print(ans) 9 | return True 10 | if curSum>sum: 11 | break 12 | curSum = curSum+arr[j] 13 | return False 14 | 15 | def subArraySum(arr,sum): 16 | n = len(arr) 17 | start = 0 18 | curSum = arr[0] 19 | i = 1 20 | while i<=n: 21 | while curSum > sum and start < i-1: 22 | curSum = curSum - arr[start] 23 | start+=1 24 | if curSum == sum: 25 | ans = str(start)+"->"+str(i-1) 26 | print(ans) 27 | return True 28 | if imax: 15 | max = cou 16 | ans = nu 17 | return ans 18 | 19 | 20 | arr = [1,1,2,2,3,3,4,4,1,1,1,5,6,5,6] 21 | opEle = mostFreqEle1(arr) 22 | print(opEle) 23 | 24 | import sys 25 | def mostFreqEle2(arr): 26 | count = {} 27 | for i in arr: 28 | if i not in count: 29 | count[i] = 1 30 | else: 31 | count[i]=count[i]+1 32 | 33 | print(count) 34 | max = -sys.maxsize 35 | ans = -1 36 | for nu,cou in count.items(): 37 | if cou>max: 38 | max = cou 39 | ans = nu 40 | return ans 41 | 42 | 43 | arr = [1,1,2,2,3,3,4,4,1,1,1,5,6,5,6] 44 | opEle = mostFreqEle2(arr) 45 | print(opEle) -------------------------------------------------------------------------------- /Level 2/Sorting/Segregate positive and negative integers using merge sort optimised.py: -------------------------------------------------------------------------------- 1 | def reverse(arr,f,l): 2 | if f negative (Ln) 18 | # arr[i:middle] -> positive (Lp) 19 | # arr[middle:j] -> negative (Rn) 20 | # arr[j:last] -> positive (Rp) 21 | 22 | reverse(arr,i,middle) # (Lp`) 23 | reverse(arr,middle+1,j-1) # (Rn`) 24 | 25 | reverse(arr,i,j-1) #(Lp`` Rn ``) 26 | 27 | # arr-> LnRnLpRp 28 | 29 | def mergeSort(arr,first,last): 30 | if firstmath.floor(len(arr)/2): 9 | return i 10 | 11 | arr = [1,1,2,2,3,3,4,4,1,1,1,1,1] 12 | opEle = majorityEle1(arr) 13 | print(opEle) 14 | 15 | def majorityEle2(arr): 16 | count = {} 17 | for i in arr: 18 | if i not in count: 19 | count[i] = 1 20 | else: 21 | count[i] = count[i]+1 22 | if count[i]>math.floor(len(arr)/2): 23 | return i 24 | 25 | arr = [1,1,2,2,3,3,4,4,1,1,1,1,1] 26 | opEle = majorityEle2(arr) 27 | print(opEle) 28 | 29 | def majorityEle3(arr): 30 | count = 0 31 | ele = -1 32 | for i in arr: 33 | if count==0: 34 | ele = i 35 | if ele == i: 36 | count+=1 37 | else: 38 | count-=1 39 | return ele 40 | 41 | arr = [1,1,2,2,3,3,4,4,1,1,1,1,1] 42 | opEle = majorityEle3(arr) 43 | print(opEle) -------------------------------------------------------------------------------- /Level 1/String/Generate all substrings of a string.py: -------------------------------------------------------------------------------- 1 | def substring1(str): 2 | subList = [] 3 | n = len(str) 4 | for i in range(n): 5 | for j in range(i+1,n+1): 6 | alpha = [] 7 | for k in range(i,j): 8 | alpha.append(str[k]) 9 | alpha = ''.join(alpha) 10 | subList.append(alpha) 11 | return subList 12 | 13 | str= "abc" 14 | subList = substring1(str) 15 | print(subList) 16 | 17 | def substring2(str): 18 | subList = [] 19 | n = len(str) 20 | for i in range(n): 21 | for j in range(i+1,n+1): 22 | subList.append(str[i:j]) 23 | return subList 24 | 25 | str= "abc" 26 | subList = substring2(str) 27 | print(subList) 28 | 29 | def substring3(str): 30 | subList = [] 31 | n = len(str) 32 | for i in range(n): 33 | temp = [] 34 | for j in range(i,n): 35 | temp.append(str[j]) 36 | alpha = ''.join(temp) 37 | subList.append(alpha) 38 | return subList 39 | 40 | str= "abc" 41 | subList = substring3(str) 42 | print(subList) -------------------------------------------------------------------------------- /Level 1/Searching/Search in rotated and sorted array.py: -------------------------------------------------------------------------------- 1 | def pivot(arr,start,end): 2 | n = len(arr) 3 | res = -1 4 | while start <= end: 5 | mid = (start+end)//2 6 | prev = (mid+n-1)%n 7 | next = (mid+1)%n 8 | if arr[mid]<=arr[next] and arr[mid]<=arr[prev]: 9 | res = mid 10 | break 11 | elif arr[start] < arr[mid]: 12 | start = mid+1 13 | elif arr[end]>arr[mid]: 14 | end = mid-1 15 | return res 16 | 17 | def binarySearch(arr,ele,start,end): 18 | ind = -1 19 | while start <=end: 20 | mid = start+ (end-start)//2 21 | if arr[mid]==ele: 22 | ind = mid 23 | break 24 | elif elecur.val: 24 | if cur.right: 25 | cur = cur.right 26 | else: 27 | cur.right = Node(data) 28 | break 29 | else: 30 | break 31 | 32 | tree = BinarySearchTree() 33 | nodes = [6,8,7,9,4,3,5] 34 | for i in nodes: 35 | tree.insert(i) 36 | 37 | print(tree.root.val) -------------------------------------------------------------------------------- /Level 1/Hashing/Two sum problem.py: -------------------------------------------------------------------------------- 1 | def twoSum1(arr,sum): 2 | pairs = [] 3 | for i in range(0,len(arr)): 4 | for j in range(i+1,len(arr)): 5 | if arr[i]+arr[j]==sum: 6 | pairs.append([arr[i],arr[j]]) 7 | return pairs 8 | 9 | arr = [1,5,7,-1,5] 10 | sum = 6 11 | pairs = twoSum1(arr,sum) 12 | print(pairs) 13 | 14 | def twoSum2(arr,sum): 15 | pairs = [] 16 | low = 0 17 | high = len(arr)-1 18 | arr.sort() 19 | while lowsum: 23 | high-=1 24 | else: 25 | low = low+1 26 | return pairs 27 | 28 | arr = [1,5,7,-1,5] 29 | sum = 6 30 | pairs = twoSum2(arr,sum) 31 | print(pairs) 32 | 33 | def twoSum3(arr,sum): 34 | pairs = [] 35 | hash = dict() 36 | for i in range(0,len(arr)): 37 | temp = sum-arr[i] 38 | if temp in hash: 39 | count = hash[temp] 40 | for j in range(count): 41 | pairs.append([temp,arr[i]]) 42 | if arr[i] in hash: 43 | hash[arr[i]]+=1 44 | else: 45 | hash[arr[i]] = 1 46 | return pairs 47 | 48 | arr = [1,5,7,-1,5] 49 | sum = 6 50 | pairs = twoSum(arr,sum) 51 | print(pairs) -------------------------------------------------------------------------------- /Level 1/Tree/Search in a tree.py: -------------------------------------------------------------------------------- 1 | # class Node: 2 | # def __init__(self,data): 3 | # self.right = None 4 | # self.left = None 5 | # self.val = data 6 | 7 | # root = Node(1) 8 | # root.left = Node(2) 9 | # root.right = Node(3) 10 | # root.left.left = Node(4) 11 | # root.left.right = Node(5) 12 | # root.left.right.left = Node(8) 13 | 14 | 15 | # def rightView(root): 16 | # q = [root,None] 17 | # row = [] 18 | # trav = [] 19 | # prev = None 20 | # while len(q)!=0: 21 | # p = q.pop(0) 22 | # if p: 23 | # row.append(p.val) 24 | # if p.left: 25 | # q.append(p.left) 26 | # if p.right: 27 | # q.append(p.right) 28 | # else: 29 | # if len(row):trav.append(row[-1]) 30 | # row = [] 31 | # q.append(None) 32 | # if p==None and prev == None: 33 | # break 34 | # prev = p 35 | # return trav 36 | 37 | # trav = rightView(root) 38 | # print(*trav) 39 | 40 | 41 | 5/0 42 | # except: 43 | # print("Some exception") 44 | 45 | print("below") -------------------------------------------------------------------------------- /Level 1/Linked List/Start of the loop.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def checkLoop(self): 11 | loopNode = None 12 | slow = self.head 13 | fast = self.head 14 | while slow and fast and fast.next: 15 | slow = slow.next 16 | fast = fast.next.next 17 | if slow==fast: 18 | loopNode = slow 19 | break 20 | return loopNode 21 | 22 | def startLoop(self): 23 | p = self.head 24 | q = self.checkLoop() 25 | while p!=q: 26 | p=p.next 27 | q = q.next 28 | return p 29 | 30 | 31 | l = LinkedList() 32 | l.head = Node(5) 33 | l.head.next = Node(1) 34 | l.head.next.next = Node(6) 35 | p = l.head.next.next 36 | l.head.next.next.next = Node(7) 37 | l.head.next.next.next.next = Node(8) 38 | l.head.next.next.next.next = p 39 | 40 | loopNode = l.checkLoop() 41 | loopStartNode = l.startLoop() 42 | print(loopStartNode.val) 43 | -------------------------------------------------------------------------------- /Level 2/Linked List/Swap pairwise nodes in a Linked List.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtEnd(self,data): 11 | cur = self.head 12 | newNode = Node(data) 13 | if cur==None: 14 | self.head = newNode 15 | else: 16 | while cur.next!=None: 17 | cur = cur.next 18 | cur.next = newNode 19 | 20 | def printList(head): 21 | cur = head 22 | while cur!=None: 23 | print(cur.val,end=" ") 24 | cur = cur.next 25 | print() 26 | 27 | def swapNodes(head): 28 | p = head 29 | if p==None: 30 | return None 31 | while p!=None: 32 | if p.next==None: 33 | break 34 | p.val, p.next.val = p.next.val, p.val 35 | p = p.next.next 36 | return head 37 | 38 | 39 | l = LinkedList() 40 | nodes_val = [1] 41 | for val in nodes_val: 42 | l.insertAtEnd(val) 43 | printList(l.head) 44 | newHead = swapNodes(l.head) 45 | printList(newHead) -------------------------------------------------------------------------------- /Level 1/Stack & Queue/Implementing Queue using linked list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class Queue: 7 | def __init__(self): 8 | self.front = None 9 | self.rear = None 10 | 11 | def enqueue(self,data): 12 | newNode = Node(data) 13 | if self.rear == None: 14 | self.front = self.rear = newNode 15 | else: 16 | self.rear.next = newNode 17 | self.rear = newNode 18 | 19 | def dequeue(self): 20 | if self.front == None: 21 | return None 22 | else: 23 | popNode = self.front 24 | self.front = self.front.next 25 | if self.front == None: 26 | self.rear = None 27 | return popNode 28 | 29 | def print(self): 30 | t = self.front 31 | while t!=None: 32 | print(t.val,end=" ") 33 | t = t.next 34 | print() 35 | 36 | q = Queue() 37 | nodes_val = [1,2,3,4,5] 38 | for i in nodes_val: 39 | q.enqueue(i) 40 | q.print() 41 | print(q.dequeue().val) 42 | q.print() -------------------------------------------------------------------------------- /Level 1/Linked List/Reverse a Linked List recursive.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def reverse(self,head): 28 | if head is None or head.next is None: 29 | return head 30 | rest = self.reverse(head.next) 31 | head.next.next = head 32 | head.next = None 33 | return rest 34 | 35 | l = LinkedList() 36 | nodes_val = [1,2,3,4,5] 37 | for val in nodes_val: 38 | l.insertAtEnd(val) 39 | l.print() #=>1 2 3 4 5 40 | l.head = l.reverse(l.head) 41 | l.print() #=> 5 4 3 2 1 -------------------------------------------------------------------------------- /Level 2/Hashing/Find whether an array is subset of another array (duplicate elements).py: -------------------------------------------------------------------------------- 1 | def isSubset(arr1,arr2): 2 | m = len(arr1) 3 | n = len(arr2) 4 | i = 0 5 | j = 0 6 | if marr2[i]: 19 | return False 20 | if i0: 36 | hashset[arr1[i]] -= 1 37 | else: 38 | return False 39 | return True 40 | 41 | arr1 = [11,1,3,13,21,7] 42 | arr2 = [11,3,7,1,3] 43 | 44 | flag = isSubset(arr1,arr2) 45 | print(flag) -------------------------------------------------------------------------------- /Level 1/Array/Find missing number in integer array of 1 to 100.py: -------------------------------------------------------------------------------- 1 | import random 2 | def listInit(): 3 | l = [] 4 | for i in range(1,101): 5 | l.append(i) 6 | missingIndex = random.randint(0,99) 7 | print("Popped element",l[missingIndex]) 8 | l.pop(missingIndex) 9 | return l 10 | 11 | def missingEle1(arr): 12 | ele = -1 13 | for i in range(1,101): 14 | if i not in arr: 15 | ele = i 16 | break 17 | return ele 18 | 19 | 20 | arr = listInit() 21 | ele = missingEle1(arr) 22 | print("Answer",ele) 23 | 24 | 25 | def missingEle2(arr): 26 | ele = -1 27 | ins = {} 28 | for i in arr: 29 | ins[i] = True 30 | for i in range(1,101): 31 | if i not in ins: 32 | ele = i 33 | break 34 | return ele 35 | 36 | 37 | ele = missingEle2(arr) 38 | print("Answer",ele) 39 | 40 | def missingEle3(arr): 41 | exp_sum = 100*101//2 42 | #actual_sum = sum(arr) 43 | actual_sum = 0 44 | for i in arr: 45 | actual_sum=actual_sum+i 46 | ele = exp_sum-actual_sum 47 | return ele 48 | 49 | 50 | ele = missingEle3(arr) 51 | print("Answer",ele) -------------------------------------------------------------------------------- /Level 1/Graph/DFS Traversal for disconnected graph.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | class Graph: 4 | def __init__(self): 5 | self.graph = defaultdict(list) 6 | 7 | def addEdge(self,u,v): 8 | self.graph[u].append(v) 9 | self.graph[v].append(u) 10 | 11 | from collections import defaultdict 12 | 13 | class Graph: 14 | def __init__(self): 15 | self.graph = defaultdict(list) 16 | 17 | def addEdge(self,u,v): 18 | self.graph[u].append(v) 19 | self.graph[v].append(u) 20 | 21 | def DFS(self,s,visited): 22 | stack = [] 23 | stack.append(s) 24 | while stack: 25 | s = stack.pop(-1) 26 | if visited[s]==False: 27 | print(s,end=" ") 28 | visited[s] = True 29 | for i in self.graph[s]: 30 | if visited[i]==False: 31 | stack.append(i) 32 | 33 | def DFS_disconnected(self): 34 | visited = [False]*(max(self.graph)+1) 35 | for i in self.graph.keys(): 36 | if not visited[i]: 37 | self.DFS(i,visited) 38 | 39 | g = Graph() 40 | g.addEdge(0, 1) 41 | g.addEdge(0, 2) 42 | g.addEdge(1, 2) 43 | g.addEdge(2, 0) 44 | g.addEdge(2, 3) 45 | g.addEdge(3, 3) 46 | g.addEdge(4,5) 47 | g.addEdge(6,7) 48 | 49 | g.DFS_disconnected() 50 | -------------------------------------------------------------------------------- /Level 1/Linked List/Reverse a Linked List iterative.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def reverse(self): 28 | cur = self.head 29 | next,prev = None, None 30 | while cur!=None: 31 | next = cur.next 32 | cur.next = prev 33 | prev = cur 34 | cur = next 35 | self.head = prev 36 | 37 | 38 | l = LinkedList() 39 | nodes_val = [1,2,3,4,5] 40 | for val in nodes_val: 41 | l.insertAtEnd(val) 42 | l.print() #=> 1 2 3 4 5 43 | l.reverse() 44 | l.print() #=> 5 4 3 2 1 45 | -------------------------------------------------------------------------------- /Level 1/Searching/Order not known Search.py: -------------------------------------------------------------------------------- 1 | def binarySearchDescending(arr,ele,start,end): 2 | ind = -1 3 | while start <=end: 4 | mid = start+ (end-start)//2 5 | if arr[mid]==ele: 6 | ind = mid 7 | break 8 | elif ele>arr[mid]: 9 | end = mid-1 10 | else: 11 | start = mid+1 12 | return ind 13 | 14 | def binarySearchAscending(arr,ele,start,end): 15 | ind = -1 16 | while start <=end: 17 | mid = start+ (end-start)//2 18 | if arr[mid]==ele: 19 | ind = mid 20 | break 21 | elif elearr[-1]: 35 | return binarySearchDescending(arr,ele,start,end) 36 | 37 | arr = [1,2,3,4] 38 | ele = 99 39 | start = 0 40 | end = len(arr)-1 41 | index = binarySearch(arr,ele,start,end) 42 | print(index) -------------------------------------------------------------------------------- /Level 1/String/Check if two string are rotation of each other or not.py: -------------------------------------------------------------------------------- 1 | class Queue: 2 | def __init__(self): 3 | self.q = [] 4 | 5 | def enque(self,data): 6 | self.q.append(data) 7 | 8 | def deque(self): 9 | popEle = -1 10 | if len(self.q)>0: 11 | popEle = self.q.pop(0) 12 | return popEle 13 | 14 | def rotationCheck1(str1,str2): 15 | if len(str1)!=len(str2): 16 | return False 17 | q1 = Queue() 18 | q2 = Queue() 19 | for i in str1: 20 | q1.enque(i) 21 | for i in str2: 22 | q2.enque(i) 23 | for i in range(len(q1.q)): 24 | alpha = q2.deque() 25 | q2.enque(alpha) 26 | if q1.q == q2.q: 27 | return True 28 | return False 29 | 30 | 31 | 32 | str1 = 'abcd' 33 | str2 = 'dab' 34 | flag = rotationCheck1(str1,str2) 35 | print(flag) 36 | 37 | 38 | def rotationCheck2(str1,str2): 39 | if len(str1)!=len(str2): 40 | return False 41 | temp = str1+str2 42 | if str2 in temp: 43 | return True 44 | return False 45 | 46 | 47 | 48 | str1 = 'abcd' 49 | str2 = 'dabc' 50 | flag = rotationCheck2(str1,str2) 51 | print(flag) -------------------------------------------------------------------------------- /Level 1/Array/Diagonal of a matrix.py: -------------------------------------------------------------------------------- 1 | def diagonal_left1(mat): 2 | dia = [] 3 | for i in range(len(mat)): 4 | for j in range(len(mat[0])): 5 | if i==j: 6 | dia.append(mat[i][j]) 7 | return dia 8 | 9 | def diagonal_right1(mat): 10 | dia = [] 11 | for i in range(len(mat)): 12 | for j in range(len(mat[0])): 13 | if i+j==len(mat)-1: 14 | dia.append(mat[i][j]) 15 | return dia 16 | 17 | mat = [ 18 | [1,2,3], 19 | [4,5,6], 20 | [7,8,9] 21 | ] 22 | 23 | dia = diagonal_left1(mat) 24 | print(dia) 25 | 26 | dia = diagonal_right1(mat) 27 | print(dia) 28 | 29 | 30 | def diagonal_left(mat): 31 | dia = [] 32 | for i in range(len(mat)): 33 | dia.append(mat[i][i]) 34 | return dia 35 | 36 | def diagonal_right(mat): 37 | dia = [] 38 | j = len(mat)-1 39 | for i in range(len(mat)): 40 | dia.append(mat[i][j]) 41 | j-=1 42 | return dia 43 | 44 | mat = [ 45 | [1,2,3], 46 | [4,5,6], 47 | [7,8,9] 48 | ] 49 | 50 | dia = diagonal_left(mat) 51 | print(dia) 52 | 53 | dia = diagonal_right(mat) 54 | print(dia) -------------------------------------------------------------------------------- /Level 1/Linked List/Remove duplicates from a sorted linked list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def removeDuplicates(self): 28 | cur = self.head 29 | while cur and cur.next: 30 | if cur.val==cur.next.val: 31 | alpha = cur.next.next 32 | cur.next = alpha 33 | else: 34 | cur = cur.next 35 | 36 | 37 | l = LinkedList() 38 | nodes_val = [1,2,2,2,3,4,5,5,5,5] 39 | for val in nodes_val: 40 | l.insertAtEnd(val) 41 | l.print() 42 | l.removeDuplicates() 43 | l.print() -------------------------------------------------------------------------------- /Level 2/Stack and Queue/Prefix expression evaluation.py: -------------------------------------------------------------------------------- 1 | def applyOperator(beta,operator,alpha): 2 | alpha = int(alpha) 3 | beta = int(beta) 4 | if operator == "+": return alpha+beta 5 | elif operator == "-": return beta-alpha 6 | elif operator == "*": return alpha*beta 7 | elif operator == "/": return alpha/beta 8 | elif operator == "^": return alpha**beta 9 | 10 | def evaluatePrefix(prefixExp): 11 | stack = [] 12 | i = 0 13 | prefixExp = prefixExp[::-1] 14 | while i 5 4 3 2 1 39 | l.deleteAtStart() 40 | l.print() #=> 4 3 2 1 41 | l.deleteAtStart() 42 | l.print() #=> 3 2 1 -------------------------------------------------------------------------------- /Level 2/Hashing/Sort an array based on order defined by another array (Relative Sorting).py: -------------------------------------------------------------------------------- 1 | def firstOccurence(arr,ele,start,end): 2 | ind = -1 3 | while start <= end: 4 | mid = (start+end)//2 5 | if ele==arr[mid]: 6 | ind = mid 7 | end = mid-1 8 | elif ele 1 2 3 4 5 41 | l.deleteAtEnd() 42 | l.print() # => 1 2 3 4 43 | l.deleteAtEnd() 44 | l.print() -------------------------------------------------------------------------------- /Level 1/Linked List/Length of loop.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def checkLoop(self): 11 | loopNode = None 12 | slow = self.head 13 | fast = self.head 14 | while slow and fast and fast.next: 15 | slow = slow.next 16 | fast = fast.next.next 17 | if slow==fast: 18 | loopNode = slow 19 | break 20 | return loopNode 21 | 22 | def lenLoop(self): 23 | len = 0 24 | p = self.checkLoop() 25 | q = self.checkLoop() 26 | while 1 : 27 | len=len+1 28 | p = p.next 29 | if p==q: 30 | break 31 | return len 32 | 33 | 34 | l = LinkedList() 35 | l.head = Node(5) 36 | l.head.next = Node(1) 37 | l.head.next.next = Node(6) 38 | p = l.head.next.next 39 | l.head.next.next.next = Node(7) 40 | l.head.next.next.next.next = Node(8) 41 | l.head.next.next.next.next.next = p 42 | 43 | loopNode = l.checkLoop() 44 | print(loopNode.val) 45 | lenLoop = l.lenLoop() 46 | print(lenLoop) 47 | -------------------------------------------------------------------------------- /Level 1/Linked List/Doubly Linked List/Deletion doubly Linked List from end.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | self.prev = None 6 | 7 | class LinkedList: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def insertAtEnd(self,data): 12 | cur = self.head 13 | newNode = Node(data) 14 | if self.head==None: 15 | self.head = newNode 16 | else: 17 | while cur.next!=None: 18 | cur = cur.next 19 | cur.next = newNode 20 | newNode.prev = cur 21 | 22 | def print(self): 23 | cur = self.head 24 | while cur!=None: 25 | print(cur.val,end=" ") 26 | cur = cur.next 27 | print() 28 | 29 | def deleteAtEnd(self): 30 | cur = self.head 31 | if cur==None or cur.next == None: 32 | self.head = None 33 | while cur.next.next != None: 34 | cur = cur.next 35 | cur.next = None 36 | 37 | l = LinkedList() 38 | nodes_val = [1,2,3,4,5] 39 | for i in nodes_val: 40 | l.insertAtEnd(i) 41 | l.print() #=>1 2 3 4 5 42 | l.deleteAtEnd() 43 | l.print() #=> 1 2 3 4 -------------------------------------------------------------------------------- /Level 2/Greedy/Huffman coding Sorted.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,freq,symbol,left=None,right=None): 3 | self.huff = '' 4 | self.freq = freq 5 | self.symbol = symbol 6 | self.left = left 7 | self.right = right 8 | 9 | def printNodes(node,val=''): 10 | newVal = val + node.huff 11 | if node.left: 12 | printNodes(node.left,newVal) 13 | if node.right: 14 | printNodes(node.right,newVal) 15 | 16 | if node.left==None and node.right == None: 17 | print(node.symbol,newVal) 18 | 19 | def insertAtSortedPos(nodes,newNode): 20 | flag = 0 21 | for i in range(len(nodes)): 22 | if nodes[i].freq > newNode.freq: 23 | flag = 1 24 | nodes.insert(i,newNode) 25 | break 26 | if flag==0: 27 | nodes.append(newNode) 28 | 29 | chars = ['a','b','c','d','e','f'] 30 | freq = [5,9,12,13,16,45] 31 | 32 | nodes = [] 33 | for x in range(len(chars)): 34 | nodes.append(Node(freq[x],chars[x])) 35 | 36 | while len(nodes)>1: 37 | left = nodes.pop(0) 38 | right = nodes.pop(0) 39 | left.huff = '0' 40 | right.huff = '1' 41 | newNode = Node( 42 | left.freq+right.freq, 43 | left.symbol+right.symbol, 44 | left, 45 | right 46 | ) 47 | # nodes.append(newNode) 48 | insertAtSortedPos(nodes,newNode) 49 | printNodes(nodes[0]) -------------------------------------------------------------------------------- /Level 1/Maths/GCD.py: -------------------------------------------------------------------------------- 1 | import math 2 | def primeFactos(n): 3 | factors = [] 4 | while n%2==0: 5 | factors.append(2) 6 | n = n//2 7 | for i in range(3,int(math.sqrt(n)+1),2): 8 | while n%i==0: 9 | factors.append(i) 10 | n = n//i 11 | if n>2: 12 | factors.append(n) 13 | return factors 14 | 15 | def gcd1(a,b): 16 | f1 = primeFactos(a) 17 | f2 = primeFactos(b) 18 | f1_count = {} 19 | f2_count = {} 20 | for i in f1: 21 | if i in f1_count: 22 | f1_count[i]=f1_count[i]+1 23 | else: 24 | f1_count[i] = 1 25 | for i in f2: 26 | if i in f2_count: 27 | f2_count[i]=f2_count[i]+1 28 | else: 29 | f2_count[i] = 1 30 | 31 | gcd_val = 1 32 | for i in list(set(f1+f2)): 33 | if i in f1_count and i in f2_count: 34 | gcd_val = gcd_val*i*min(f1_count[i],f2_count[i]) 35 | return gcd_val 36 | 37 | def gcd2(a,b): 38 | if a==0: 39 | return b 40 | if b==0: 41 | return a 42 | if a==b: 43 | return a 44 | if a>b: 45 | return gcd2(a-b,b) 46 | return gcd2(a,b-a) 47 | 48 | def gcd3(a,b): 49 | if b==0: 50 | return a 51 | return gcd3(b,a%b) 52 | 53 | a = 20 54 | b = 28 55 | 56 | gcd_val = gcd1(a,b) 57 | print(gcd_val) 58 | 59 | gcd_val = gcd2(a,b) 60 | print(gcd_val) 61 | 62 | gcd_val = gcd3(a,b) 63 | print(gcd_val) 64 | 65 | -------------------------------------------------------------------------------- /Level 1/Tree/Height of tree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.left = None 5 | self.right = None 6 | 7 | class BinarySearchTree: 8 | def __init__(self): 9 | self.root = None 10 | 11 | def insert(self,data): 12 | if self.root == None: 13 | self.root = Node(data) 14 | else: 15 | cur = self.root 16 | while 1: 17 | if datacur.val: 24 | if cur.right: 25 | cur = cur.right 26 | else: 27 | cur.right = Node(data) 28 | break 29 | else: 30 | break 31 | 32 | def height(root): 33 | if root==None: 34 | return 0 35 | return 1+max(height(root.left),height(root.right)) 36 | 37 | tree = BinarySearchTree() 38 | nodes = [6,8,7,9,4,3,5] 39 | for i in nodes: 40 | tree.insert(i) 41 | 42 | heightValue = height(tree.root) 43 | print(heightValue) -------------------------------------------------------------------------------- /Level 1/Tree/Sum of all nodes.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.left = None 5 | self.right = None 6 | 7 | class BinarySearchTree: 8 | def __init__(self): 9 | self.root = None 10 | 11 | def insert(self,data): 12 | if self.root == None: 13 | self.root = Node(data) 14 | else: 15 | cur = self.root 16 | while 1: 17 | if datacur.val: 24 | if cur.right: 25 | cur = cur.right 26 | else: 27 | cur.right = Node(data) 28 | break 29 | else: 30 | break 31 | def sum(root): 32 | if root==None: 33 | return 0 34 | return root.val+sum(root.left)+sum(root.right) 35 | 36 | tree = BinarySearchTree() 37 | nodes = [6,8,7,9,4,3,5] 38 | print(sum(nodes)) 39 | for i in nodes: 40 | tree.insert(i) 41 | 42 | # sumValue = sum(tree.root) 43 | # print(sumValue) -------------------------------------------------------------------------------- /Level 2/Array/Triplet sum.py: -------------------------------------------------------------------------------- 1 | def twoSum2(arr,sum): 2 | low = 0 3 | high = len(arr)-1 4 | arr.sort() 5 | while lowsum: 9 | high-=1 10 | else: 11 | low = low+1 12 | return False 13 | 14 | def tripletSum(arr,sum): 15 | n = len(arr) 16 | for i in range(0,n-2): 17 | for j in range(i+1,n-1): 18 | for k in range(j+1,n): 19 | if arr[i]+arr[j]+arr[k] == sum: 20 | print(arr[i],arr[j],arr[k]) 21 | return True 22 | return False 23 | 24 | def tripletSum(arr,sum): 25 | n = len(arr) 26 | hash = {} 27 | for i in range(0,n): 28 | for j in range(i+1,n): 29 | temp = sum-arr[i]-arr[j] 30 | if temp in hash: 31 | print(arr[i],arr[j],sum-arr[i]-arr[j]) 32 | return True 33 | hash[arr[i]] = True 34 | return False 35 | 36 | def tripletSum(arr,sum): 37 | n = len(arr) 38 | arr.sort() 39 | for i in range(0,n-2): 40 | if twoSum2(arr[i+1:n],sum-arr[i]) == True: 41 | return True 42 | return False 43 | 44 | arr =[1,4,45,6,10,8] 45 | sum = 22 46 | isThere = tripletSum(arr,sum) 47 | print(isThere) -------------------------------------------------------------------------------- /Level 1/Linked List/Check length of Linked List is even or odd without couting nodes.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def evenOrOdd(self): 28 | cur = self.head 29 | state = None 30 | while 1: 31 | if cur==None: 32 | state = "even" 33 | break 34 | elif cur.next == None: 35 | state = "odd" 36 | break 37 | cur = cur.next.next 38 | return state 39 | 40 | l = LinkedList() 41 | nodes_val = [1,2,3,4] 42 | for val in nodes_val: 43 | l.insertAtEnd(val) 44 | l.print() 45 | state = l.evenOrOdd() 46 | print(state) 47 | -------------------------------------------------------------------------------- /Level 1/Dynamic Programming/Printing LCS.py: -------------------------------------------------------------------------------- 1 | def lcs(x,y,n,m): 2 | dp = [] 3 | for i in range(n+1): 4 | row = [] 5 | for j in range(m+1): 6 | if i==0 or j==0: 7 | row.append(0) 8 | else: 9 | row.append(-1) 10 | dp.append(row) 11 | 12 | # for i in dp: 13 | # print(*i) 14 | 15 | for i in range(1,n+1): 16 | for j in range(1,m+1): 17 | if x[i-1] == y[j-1]: 18 | dp[i][j] = 1+dp[i-1][j-1] 19 | else: 20 | dp[i][j] = max(dp[i][j-1],dp[i-1][j]) 21 | 22 | # for i in dp: 23 | # print(*i) 24 | 25 | # return dp[-1][-1] 26 | 27 | return dp 28 | 29 | def printlcs(x,y,n,m): 30 | dp = lcs(x,y,n,m) 31 | ans = [] 32 | i = n 33 | j = m 34 | while i>0 or j>0: 35 | if x[i-1] == y[j-1]: 36 | ans.append(x[i-1]) 37 | i-=1 38 | j-=1 39 | else: 40 | if dp[i][j-1]>dp[i-1][j]: 41 | j=j-1 42 | else: 43 | i = i-1 44 | ans.reverse() 45 | ans = ''.join(ans) 46 | return ans 47 | 48 | 49 | x = "abcde" 50 | y = "ace" 51 | n = len(x) 52 | m = len(y) 53 | lcs_str = printlcs(x,y,n,m) 54 | print(lcs_str) -------------------------------------------------------------------------------- /Level 1/Linked List/Count of every element in a linked list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def count(self): 28 | hash = {} 29 | cur = self.head 30 | while cur!=None: 31 | if cur.val not in hash: 32 | hash[cur.val] = 1 33 | else: 34 | hash[cur.val] = hash[cur.val]+1 35 | cur = cur.next 36 | return hash 37 | 38 | l = LinkedList() 39 | nodes_val = [1,2,2,1,5,7,4,3,4,5] 40 | for val in nodes_val: 41 | l.insertAtEnd(val) 42 | l.print() 43 | countDict = l.count() 44 | for key,value in countDict.items(): 45 | print("Count of element",key,"is",value) -------------------------------------------------------------------------------- /Level 2/Maths/Computing value of nCr.py: -------------------------------------------------------------------------------- 1 | #Brute 2 | def fact(n): 3 | res = 1 4 | for i in range(2,n+1): 5 | res=res*i 6 | return res 7 | 8 | def nCr(n,r): 9 | return fact(n)//(fact(r)*fact(n-r)) 10 | 11 | n = 5 12 | r = 2 13 | print(nCr(n,r)) 14 | 15 | #Recursive 16 | def nCr(n,r): 17 | if r>n: 18 | return 0 19 | elif r==0 or r==n: 20 | return 1 21 | return nCr(n-1,r-1)+nCr(n-1,r) 22 | 23 | n = 5 24 | r = 2 25 | print(nCr(n,r)) 26 | 27 | #Memorised 28 | def nCrUtil(n,r,dp): 29 | if dp[n][r]!=-1: 30 | return dp[n][r] 31 | if r==0 or r==n: 32 | dp[n][r] = 1 33 | return dp[n][r] 34 | dp[n][r] = nCr(n-1,r-1)+nCr(n-1,r) 35 | return dp[n][r] 36 | 37 | def nCr(n,k): 38 | dp = [[-1 for y in range(k+1)] 39 | for x in range(n+1)] 40 | return nCrUtil(n,k,dp) 41 | 42 | n = 5 43 | r = 2 44 | print(nCr(n,r)) 45 | 46 | def nCr(n,k): 47 | dp = [[-1 for y in range(k+1)] 48 | for x in range(n+1)] 49 | 50 | for i in range(0,n+1): 51 | for j in range(0,k+1): 52 | if j==0 or j==i: 53 | dp[i][j] = 1 54 | else: 55 | dp[i][j] = dp[i-1][j-1]+dp[i-1][j] 56 | return dp[-1][-1] 57 | 58 | n = 5 59 | r = 2 60 | print(nCr(n,r)) -------------------------------------------------------------------------------- /Level 1/Linked List/Doubly Linked List/Reverse a doubly linked list recursive.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | self.prev = None 6 | 7 | class LinkedList: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def insertAtEnd(self,data): 12 | cur = self.head 13 | newNode = Node(data) 14 | if self.head==None: 15 | self.head = newNode 16 | else: 17 | while cur.next!=None: 18 | cur = cur.next 19 | cur.next = newNode 20 | newNode.prev = cur 21 | 22 | def print(self): 23 | cur = self.head 24 | while cur!=None: 25 | print(cur.val,end=" ") 26 | cur = cur.next 27 | print() 28 | 29 | def reverse(self,head): 30 | if head==None or head.next == None: 31 | return head 32 | rest = self.reverse(head.next) 33 | alpha = head.next 34 | head.next.next = head 35 | head.next = None 36 | head.prev = alpha 37 | return rest 38 | 39 | l = LinkedList() 40 | nodes_val = [1,2,3,4,5] 41 | for i in nodes_val: 42 | l.insertAtEnd(i) 43 | l.print() #=>1 2 3 4 5 44 | l.head = l.reverse(l.head) 45 | l.print() #=> 5 4 3 2 1 -------------------------------------------------------------------------------- /Level 2/Linked List/Swap pairwise nodes in a Linked List without swapping data.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtEnd(self,data): 11 | cur = self.head 12 | newNode = Node(data) 13 | if cur==None: 14 | self.head = newNode 15 | else: 16 | while cur.next!=None: 17 | cur = cur.next 18 | cur.next = newNode 19 | 20 | def printList(head): 21 | cur = head 22 | while cur!=None: 23 | print(cur.val,end=" ") 24 | cur = cur.next 25 | print() 26 | 27 | def swapNodes(head): 28 | p = head 29 | if p==None or p.next == None: 30 | return head 31 | newHead = p.next 32 | while 1: 33 | q = p.next 34 | temp = q.next 35 | q.next = p 36 | if temp==None or temp.next==None: 37 | p.next = temp 38 | break 39 | p.next = temp.next 40 | p = temp 41 | return newHead 42 | 43 | 44 | l = LinkedList() 45 | nodes_val = [1,2,3,4,5] 46 | for val in nodes_val: 47 | l.insertAtEnd(val) 48 | printList(l.head) 49 | newHead = swapNodes(l.head) 50 | printList(newHead) -------------------------------------------------------------------------------- /Level 1/Maths/LCM.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | def gcd(a,b): 4 | if b==0: 5 | return a 6 | return gcd(b,a%b) 7 | 8 | def primeFactos(n): 9 | factors = [] 10 | while n%2==0: 11 | factors.append(2) 12 | n = n//2 13 | for i in range(3,int(math.sqrt(n)+1),2): 14 | while n%i==0: 15 | factors.append(i) 16 | n = n//i 17 | if n>2: 18 | factors.append(n) 19 | return factors 20 | 21 | def lcm1(a,b): 22 | f1 = primeFactos(a) 23 | f2 = primeFactos(b) 24 | f1_count = {} 25 | f2_count = {} 26 | for i in f1: 27 | if i in f1_count: 28 | f1_count[i]=f1_count[i]+1 29 | else: 30 | f1_count[i] = 1 31 | for i in f2: 32 | if i in f2_count: 33 | f2_count[i]=f2_count[i]+1 34 | else: 35 | f2_count[i] = 1 36 | 37 | lcm_val = 1 38 | for i in list(set(f1+f2)): 39 | if i in f1_count and i in f2_count: 40 | if f1_count[i]>f2_count[i]: 41 | alpha = f2_count[i]+(f1_count[i]-f2_count[i]) 42 | else: 43 | alpha = f1_count[i]+(f2_count[i]-f1_count[i]) 44 | elif i in f1_count: 45 | alpha = f1_count[i] 46 | else: 47 | alpha = f2_count[i] 48 | lcm_val = lcm_val*i*alpha 49 | return lcm_val 50 | 51 | def lcm2(a,b): 52 | return a*b//gcd(a,b) 53 | 54 | a = 15 55 | b = 20 56 | 57 | lcm_val = lcm1(a,b) 58 | print(lcm_val) 59 | 60 | 61 | lcm_val = lcm2(a,b) 62 | print(lcm_val) 63 | -------------------------------------------------------------------------------- /Level 2/Linked List/Merge two Linked Lists at alternate positions.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtEnd(self,data): 11 | cur = self.head 12 | newNode = Node(data) 13 | if cur==None: 14 | self.head = newNode 15 | else: 16 | while cur.next!=None: 17 | cur = cur.next 18 | cur.next = newNode 19 | 20 | def printList(head): 21 | cur = head 22 | while cur!=None: 23 | print(cur.val,end=" ") 24 | cur = cur.next 25 | print() 26 | 27 | def merge(h1,h2): 28 | p = h1 29 | q = h2 30 | while p!=None and q!=None: 31 | pNext = p.next 32 | qNext = q.next 33 | q.next = pNext 34 | p.next = q 35 | 36 | p = pNext 37 | q = qNext 38 | return h1 39 | 40 | 41 | l1 = LinkedList() 42 | nodes_val = [1,2,3,4,5] 43 | for val in nodes_val: 44 | l1.insertAtEnd(val) 45 | printList(l1.head) 46 | 47 | l2 = LinkedList() 48 | nodes_val = [6,7,8,9,10] 49 | for val in nodes_val: 50 | l2.insertAtEnd(val) 51 | printList(l2.head) 52 | 53 | newHead = merge(l1.head,l2.head) 54 | printList(newHead) -------------------------------------------------------------------------------- /Level 1/Tree/Number of nodes.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.left = None 5 | self.right = None 6 | 7 | class BinarySearchTree: 8 | def __init__(self): 9 | self.root = None 10 | 11 | def insert(self,data): 12 | if self.root == None: 13 | self.root = Node(data) 14 | else: 15 | cur = self.root 16 | while 1: 17 | if datacur.val: 24 | if cur.right: 25 | cur = cur.right 26 | else: 27 | cur.right = Node(data) 28 | break 29 | else: 30 | break 31 | 32 | count = 0 33 | def numberOfNodes(root): 34 | if root==None: 35 | return 0 36 | global count 37 | count=count+1 38 | numberOfNodes(root.left),numberOfNodes(root.right) 39 | 40 | tree = BinarySearchTree() 41 | nodes = [6,8,7,9,4,3,5] 42 | for i in nodes: 43 | tree.insert(i) 44 | 45 | numberOfNodes(tree.root) 46 | print(count) -------------------------------------------------------------------------------- /Level 1/Linked List/Doubly Linked List/Reverse a doubly linked list iterative.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | self.prev = None 6 | 7 | class LinkedList: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def insertAtEnd(self,data): 12 | cur = self.head 13 | newNode = Node(data) 14 | if self.head==None: 15 | self.head = newNode 16 | else: 17 | while cur.next!=None: 18 | cur = cur.next 19 | cur.next = newNode 20 | newNode.prev = cur 21 | 22 | def print(self): 23 | cur = self.head 24 | while cur!=None: 25 | print(cur.val,end=" ") 26 | cur = cur.next 27 | print() 28 | 29 | def reverse(self): 30 | cur = self.head 31 | while cur!=None: 32 | temp = cur.prev 33 | cur.prev = cur.next 34 | cur.next = temp 35 | cur = cur.prev 36 | 37 | if temp!=None: 38 | self.head = temp.prev 39 | 40 | l = LinkedList() 41 | nodes_val = [1,2,3,4,5] 42 | for i in nodes_val: 43 | l.insertAtEnd(i) 44 | l.print() #=> 1 2 3 4 5 45 | l.reverse() 46 | l.print() #=> 5 4 3 2 1 -------------------------------------------------------------------------------- /Level 1/Tree/Preorder traversal recursive.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.left = None 5 | self.right = None 6 | 7 | class BinarySearchTree: 8 | def __init__(self): 9 | self.root = None 10 | 11 | def insert(self,data): 12 | if self.root == None: 13 | self.root = Node(data) 14 | else: 15 | cur = self.root 16 | while 1: 17 | if datacur.val: 24 | if cur.right: 25 | cur = cur.right 26 | else: 27 | cur.right = Node(data) 28 | break 29 | else: 30 | break 31 | 32 | traversal = [] 33 | def preorder(root): 34 | if root==None: 35 | return 36 | global traversal 37 | traversal.append(root.val) 38 | preorder(root.left) 39 | preorder(root.right) 40 | 41 | tree = BinarySearchTree() 42 | nodes = [6,8,7,9,4,3,5] 43 | for i in nodes: 44 | tree.insert(i) 45 | preorder(tree.root) 46 | print(*traversal) -------------------------------------------------------------------------------- /Level 1/Tree/Inorder traversal recursive.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.left = None 5 | self.right = None 6 | 7 | class BinarySearchTree: 8 | def __init__(self): 9 | self.root = None 10 | 11 | def insert(self,data): 12 | if self.root == None: 13 | self.root = Node(data) 14 | else: 15 | cur = self.root 16 | while 1: 17 | if datacur.val: 24 | if cur.right: 25 | cur = cur.right 26 | else: 27 | cur.right = Node(data) 28 | break 29 | else: 30 | break 31 | 32 | traversal = [] 33 | def inorder(root): 34 | if root==None: 35 | return 36 | inorder(root.left) 37 | global traversal 38 | traversal.append(root.val) 39 | inorder(root.right) 40 | 41 | tree = BinarySearchTree() 42 | nodes = [6,8,7,9,4,3,5] 43 | for i in nodes: 44 | tree.insert(i) 45 | 46 | inorder(tree.root) 47 | print(*traversal) -------------------------------------------------------------------------------- /Level 1/Linked List/Circular Linked List/Deletion Circular Linked List from start.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.last = None 9 | 10 | def insertAtStart(self,data): 11 | newNode = Node(data) 12 | if self.last==None: 13 | self.last = newNode 14 | newNode.next = self.last 15 | else: 16 | newNode.next = self.last.next 17 | self.last.next = newNode 18 | 19 | def print(self): 20 | if self.last==None: 21 | return None 22 | cur = self.last.next 23 | 24 | while 1: 25 | print(cur.val,end=" ") 26 | if cur==self.last: 27 | break 28 | cur = cur.next 29 | print() 30 | 31 | def deleteAtStart(self): 32 | if self.last==None: 33 | return None 34 | if self.last.next == self.last: 35 | self.last=None 36 | else: 37 | self.last.next = self.last.next.next 38 | 39 | l = LinkedList() 40 | nodes_val = [1,2,3,4,5] 41 | for i in nodes_val: 42 | l.insertAtStart(i) 43 | l.print() #=> 5 4 3 2 1 44 | l.deleteAtStart() 45 | l.print() #=> 4 3 2 1 46 | l.deleteAtStart() 47 | l.print() #=> 3 2 1 -------------------------------------------------------------------------------- /Level 1/Tree/Postorder traversal recursive.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.left = None 5 | self.right = None 6 | 7 | class BinarySearchTree: 8 | def __init__(self): 9 | self.root = None 10 | 11 | def insert(self,data): 12 | if self.root == None: 13 | self.root = Node(data) 14 | else: 15 | cur = self.root 16 | while 1: 17 | if datacur.val: 24 | if cur.right: 25 | cur = cur.right 26 | else: 27 | cur.right = Node(data) 28 | break 29 | else: 30 | break 31 | traversal = [] 32 | 33 | def postOrder(root): 34 | if root==None: 35 | return 36 | postOrder(root.left) 37 | postOrder(root.right) 38 | global traversal 39 | traversal.append(root.val) 40 | 41 | tree = BinarySearchTree() 42 | nodes = [6,8,7,9,4,3,5] 43 | for i in nodes: 44 | tree.insert(i) 45 | postOrder(tree.root) 46 | print(*traversal) 47 | -------------------------------------------------------------------------------- /Level 1/Maths/Grid Unique Paths.py: -------------------------------------------------------------------------------- 1 | def fact(n): 2 | res = 1 3 | for i in range(1,n+1): 4 | res = res*i 5 | return res 6 | 7 | def nCr(n,r): 8 | return fact(n)// (fact(r)*fact(n-r)) 9 | 10 | def uniquePaths1(i,j,x,y): 11 | if i==x-1 and j==y-1: 12 | return 1 13 | elif i>=x or j>=y: 14 | return 0 15 | else: 16 | return uniquePaths1(i+1,j,x,y)+uniquePaths1(i,j+1,x,y) 17 | 18 | def uniquePaths2(i,j,x,y,dp): 19 | if i==x-1 and j==y-1: 20 | dp[i][j] = 1 21 | return 1 22 | elif i>=x or j>=y: 23 | dp[i][j] = 0 24 | return 0 25 | else: 26 | if dp[i+1][j]==-1: 27 | alpha = uniquePaths2(i+1,j,x,y,dp) 28 | else: 29 | alpha = dp[i+1][j] 30 | if dp[i][j+1]==-1: 31 | beta = uniquePaths2(i,j+1,x,y,dp) 32 | else: 33 | beta = dp[i][j+1] 34 | return alpha+beta 35 | 36 | def uniquePaths3(i,j,x,y): 37 | return nCr(x+y-2-i-j,y-1-j) 38 | 39 | i,j = 0,0 40 | x,y = 2,3 41 | paths = uniquePaths1(i,j,x,y) 42 | print(paths) 43 | 44 | dp = [] 45 | for _ in range(x+1): 46 | row = [] 47 | for __ in range(y+1): 48 | row.append(-1) 49 | dp.append(row) 50 | 51 | 52 | paths = uniquePaths2(i,j,x,y,dp) 53 | print(paths) 54 | 55 | paths = uniquePaths3(i,j,x,y) 56 | print(paths) -------------------------------------------------------------------------------- /Level 1/Linked List/Find Nth Node from End of Linked list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def nthNodeFromEnd(self,n): 28 | if self.head==None: 29 | return None 30 | ahead = self.head 31 | behind = self.head 32 | while ahead!=None and n-1>0: 33 | ahead = ahead.next 34 | n=n-1 35 | if ahead==None: 36 | return None 37 | while ahead.next!=None: 38 | ahead = ahead.next 39 | behind = behind.next 40 | return behind 41 | 42 | l = LinkedList() 43 | nodes_val = [1,2,3,4,5] 44 | for val in nodes_val: 45 | l.insertAtEnd(val) 46 | l.print() 47 | n = 9 48 | nthNode = l.nthNodeFromEnd(n) 49 | print(nthNode) -------------------------------------------------------------------------------- /Level 1/Linked List/Insertion Singly Linked List at middle.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def search(self,key): 28 | cur = self.head 29 | keyNode = None 30 | while cur!=None: 31 | if cur.val==key: 32 | keyNode = cur 33 | break 34 | cur = cur.next 35 | return keyNode 36 | 37 | def insertAtMiddle(self,data,pos): 38 | newNode = Node(data) 39 | store = pos.next 40 | pos.next = newNode 41 | newNode.next = store 42 | 43 | 44 | l = LinkedList() 45 | nodes_val = [1,2,3,4,5] 46 | for val in nodes_val: 47 | l.insertAtEnd(val) 48 | l.print() 49 | posValue = 3 50 | posNode = l.search(posValue) 51 | data = 10 52 | l.insertAtMiddle(data,posNode) 53 | l.print() -------------------------------------------------------------------------------- /Level 2/Hashing/Find whether an array is subset of another array (distinct elements).py: -------------------------------------------------------------------------------- 1 | def binarySearch(arr,ele,start,end): 2 | ind = -1 3 | while start <=end: 4 | mid = start+ (end-start)//2 5 | if arr[mid]==ele: 6 | ind = mid 7 | break 8 | elif ele 1 2 3 4 5 48 | posValue = 3 49 | posNode = l.search(posValue) 50 | deleteWithoutHeadPointer(posNode) 51 | l.print() #=> 1 2 4 5 -------------------------------------------------------------------------------- /Level 1/Maths/Search in a sorted 2D matrix.py: -------------------------------------------------------------------------------- 1 | def binarySearch(arr,ele,start,end): 2 | ind = -1 3 | while start <=end: 4 | mid = start+ (end-start)//2 5 | if arr[mid]==ele: 6 | ind = mid 7 | break 8 | elif ele=0: 38 | if mat[i][j]==target: 39 | return [i,j] 40 | elif mat[i][j]>target: 41 | j-=1 42 | else: 43 | i+=1 44 | return -1 45 | 46 | mat = [ 47 | [1,3,5,7], 48 | [10,11,16,20], 49 | [23,30,34,60] 50 | ] 51 | target = 110 52 | 53 | ind = search1(mat,target) 54 | print(ind) 55 | ind = search2(mat,target) 56 | print(ind) 57 | ind = search3(mat,target) 58 | print(ind) -------------------------------------------------------------------------------- /Level 1/Tree/Number of leaf nodes.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Node: 4 | def __init__(self,data): 5 | self.val = data 6 | self.left = None 7 | self.right = None 8 | 9 | class BinarySearchTree: 10 | def __init__(self): 11 | self.root = None 12 | 13 | def insert(self,data): 14 | if self.root == None: 15 | self.root = Node(data) 16 | else: 17 | cur = self.root 18 | while 1: 19 | if datacur.val: 26 | if cur.right: 27 | cur = cur.right 28 | else: 29 | cur.right = Node(data) 30 | break 31 | else: 32 | break 33 | 34 | count = 0 35 | def numberOfLeafNodes(root): 36 | if root: 37 | if root.left==None and root.right==None: 38 | global count 39 | count=count+1 40 | else: 41 | numberOfLeafNodes(root.left),numberOfLeafNodes(root.right) 42 | 43 | tree = BinarySearchTree() 44 | nodes = [6,8,7,9,4,3,5] 45 | for i in nodes: 46 | tree.insert(i) 47 | 48 | numberOfLeafNodes(tree.root) 49 | print(count) -------------------------------------------------------------------------------- /Level 2/Linked List/Insert at sorted position in a sorted Linked List.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def insertInSorted(self,key): 28 | cur = self.head 29 | pos = None 30 | while cur!=None: 31 | if cur.val > key: 32 | break 33 | pos = cur 34 | cur = cur.next 35 | if pos==None: 36 | temp = cur 37 | self.head = Node(key) 38 | self.head.next = temp 39 | else: 40 | temp = pos.next 41 | pos.next = Node(key) 42 | pos.next.next = temp 43 | 44 | l = LinkedList() 45 | nodes_val = [1,2,3,7,9,11] 46 | for val in nodes_val: 47 | l.insertAtEnd(val) 48 | l.print() 49 | 50 | key = 5 51 | l.insertInSorted(key) 52 | 53 | l.print() -------------------------------------------------------------------------------- /Level 2/Linked List/Check whether a Linked List is sorted or not.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def sortedOrNot(head): 28 | if head==None or head.next == None: 29 | return True 30 | return head.val cur.val: 39 | return False 40 | prev = cur 41 | cur = cur.next 42 | return True 43 | 44 | l = LinkedList() 45 | nodes_val = [1,2,3,4,5] 46 | for val in nodes_val: 47 | l.insertAtEnd(val) 48 | l.print() 49 | 50 | flag = sortedOrNot(l.head) 51 | print(flag) 52 | 53 | flag = sortedOrNot2(l.head) 54 | print(flag) -------------------------------------------------------------------------------- /Level 2/Sorting/Inversion count of an array.py: -------------------------------------------------------------------------------- 1 | def inversionCount(arr): 2 | count = 0 3 | for i in range(0,len(arr)): 4 | for j in range(i+1,len(arr)): 5 | if arr[i] > arr[j]: 6 | print(arr[i],arr[j]) 7 | count+=1 8 | return count 9 | 10 | arr = [1,20,6,4,5] 11 | count = inversionCount(arr) 12 | print(count) 13 | 14 | def merge(arr,first,middle,last): 15 | arr1 = arr[first:middle+1] 16 | arr2 = arr[middle+1:last+1] 17 | i = 0 18 | j = 0 19 | k = first 20 | count = 0 21 | 22 | while imax: 19 | max = sum(i) 20 | return max 21 | 22 | arr = [-2,1,-3,4,-1,2,1,-5,4] 23 | max_sum = maxSubArraySum(arr) 24 | print(max_sum) 25 | 26 | def maxSubArraySum2(arr): 27 | n = len(arr) 28 | max = -sys.maxsize 29 | for i in range(n): 30 | temp = 0 31 | for j in range(i,n): 32 | temp = temp+arr[j] 33 | if temp>max: 34 | max = temp 35 | return max 36 | 37 | arr = [-2,1,-3,4,-1,2,1,-5,4] 38 | max_sum = maxSubArraySum2(arr) 39 | print(max_sum) 40 | 41 | def maxSubArraySum3(arr): 42 | n = len(arr) 43 | max_so_far = -sys.maxsize 44 | max = 0 45 | for i in range(n): 46 | max = max+i 47 | if max_so_farcur.val: 24 | if cur.right: 25 | cur = cur.right 26 | else: 27 | cur.right = Node(data) 28 | break 29 | else: 30 | break 31 | 32 | def levelOrder(root): 33 | traversal = [] 34 | q = [root] 35 | while len(q)!=0: 36 | p = q.pop(0) 37 | if p: 38 | traversal.append(p.val) 39 | if p.left: 40 | q.append(p.left) 41 | if p.right: 42 | q.append(p.right) 43 | return traversal 44 | 45 | tree = BinarySearchTree() 46 | nodes = [6,8,7,9,4,3,5] 47 | for i in nodes: 48 | tree.insert(i) 49 | 50 | traversal = levelOrder(tree.root) 51 | print(traversal) -------------------------------------------------------------------------------- /Level 1/Linked List/Doubly Linked List/Deletion doubly Linked List from middle.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | self.prev = None 6 | 7 | class LinkedList: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def insertAtStart(self,data): 12 | newNode = Node(data) 13 | if self.head==None: 14 | self.head = newNode 15 | else: 16 | self.head.prev = newNode 17 | newNode.next = self.head 18 | self.head = newNode 19 | 20 | def print(self): 21 | cur = self.head 22 | while cur!=None: 23 | print(cur.val,end=" ") 24 | cur = cur.next 25 | print() 26 | 27 | def search(self,key): 28 | cur = self.head 29 | keyNode = None 30 | while cur!=None: 31 | if cur.val == key: 32 | keyNode = cur 33 | break 34 | cur = cur.next 35 | return keyNode 36 | 37 | def deleteAtMiddle(self,pos): 38 | cur = self.head 39 | if cur==None or cur==pos: 40 | return None 41 | prev = pos.prev 42 | prev.next = pos.next 43 | pos.next.prev = pos 44 | 45 | l = LinkedList() 46 | nodes_val = [1,2,3,4,5] 47 | for i in nodes_val: 48 | l.insertAtStart(i) 49 | l.print() #=> 5 4 3 2 1 50 | posValue = 3 51 | posNode = l.search(posValue) 52 | l.deleteAtMiddle(posNode) 53 | l.print() #=> 5 4 2 1 -------------------------------------------------------------------------------- /Level 1/Linked List/Circular Linked List/Deletion Circular Linked List from end.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.last = None 9 | 10 | def insertAtEnd(self,data): 11 | newNode = Node(data) 12 | if self.last==None: 13 | self.last = newNode 14 | newNode.next = self.last 15 | else: 16 | newNode.next = self.last.next 17 | self.last.next = newNode 18 | self.last = newNode 19 | 20 | def print(self): 21 | if self.last==None: 22 | return None 23 | cur = self.last.next 24 | 25 | while 1: 26 | print(cur.val,end=" ") 27 | if cur==self.last: 28 | break 29 | cur = cur.next 30 | print() 31 | 32 | def deleteAtEnd(self): 33 | if self.last==None: 34 | return None 35 | if self.last.next == self.last: 36 | self.last = None 37 | else: 38 | cur = self.last.next 39 | while cur.next!=self.last: 40 | cur = cur.next 41 | cur.next = self.last.next 42 | self.last = cur 43 | 44 | l = LinkedList() 45 | nodes_val = [1,2,3,4,5] 46 | for i in nodes_val: 47 | l.insertAtEnd(i) 48 | l.print() #=> 1 2 3 4 5 49 | l.deleteAtEnd() 50 | l.print() #=> 1 2 3 4 51 | l.deleteAtEnd() 52 | l.print() #=> 1 2 3 -------------------------------------------------------------------------------- /Level 2/Linked List/Rotate the Linked List around a specific node.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insertAtEnd(self,data): 11 | cur = self.head 12 | newNode = Node(data) 13 | if cur==None: 14 | self.head = newNode 15 | else: 16 | while cur.next!=None: 17 | cur = cur.next 18 | cur.next = newNode 19 | 20 | def search(self,key): 21 | cur = self.head 22 | keyNode = None 23 | while cur!=None: 24 | if cur.val == key: 25 | keyNode = cur 26 | break 27 | cur=cur.next 28 | return keyNode 29 | 30 | def printList(head): 31 | cur = head 32 | while cur!=None: 33 | print(cur.val,end=" ") 34 | cur = cur.next 35 | print() 36 | 37 | def rotate(head,rNode): 38 | p = head 39 | while p!=None: 40 | if p==rNode: 41 | break 42 | p = p.next 43 | newHead = p.next 44 | p.next = None 45 | q = newHead 46 | while q.next!=None: 47 | q = q.next 48 | q.next = head 49 | return newHead 50 | 51 | l = LinkedList() 52 | nodes_val = [1,2,3,4,5] 53 | for val in nodes_val: 54 | l.insertAtEnd(val) 55 | printList(l.head) 56 | key = 3 57 | keyNode = l.search(key) 58 | newHead = rotate(l.head,keyNode) 59 | printList(newHead) -------------------------------------------------------------------------------- /Level 1/Linked List/Remove duplicates from a unsorted linked list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def print(self): 11 | cur = self.head 12 | while cur!=None: 13 | print(cur.val,end=" ") 14 | cur = cur.next 15 | print() 16 | 17 | def insertAtEnd(self,data): 18 | cur = self.head 19 | newNode = Node(data) 20 | if cur==None: 21 | self.head = newNode 22 | else: 23 | while cur.next!=None: 24 | cur = cur.next 25 | cur.next = newNode 26 | 27 | def deleteAtMiddle(self,pos): 28 | cur = self.head 29 | if cur==pos or cur==None: 30 | self.head = None 31 | else: 32 | prev = None 33 | while cur!=pos: 34 | prev = cur 35 | cur = cur.next 36 | prev.next = cur.next 37 | 38 | 39 | def removeDuplicates(self): 40 | hash = {} 41 | cur = self.head 42 | while cur!=None: 43 | if cur.val not in hash: 44 | hash[cur.val] = True 45 | else: 46 | self.deleteAtMiddle(cur) 47 | cur = cur.next 48 | 49 | l = LinkedList() 50 | nodes_val = [4,1,2,3,4,2,5] 51 | for val in nodes_val: 52 | l.insertAtEnd(val) 53 | l.print() 54 | l.removeDuplicates() 55 | l.print() -------------------------------------------------------------------------------- /Level 1/Tree/Preorder traversal iterative.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.left = None 5 | self.right = None 6 | 7 | class BinarySearchTree: 8 | def __init__(self): 9 | self.root = None 10 | 11 | def insert(self,data): 12 | if self.root == None: 13 | self.root = Node(data) 14 | else: 15 | cur = self.root 16 | while 1: 17 | if datacur.val: 24 | if cur.right: 25 | cur = cur.right 26 | else: 27 | cur.right = Node(data) 28 | break 29 | else: 30 | break 31 | 32 | 33 | def preorder(root): 34 | traversal = [] 35 | cur = root 36 | stack = [] 37 | while 1: 38 | while cur: 39 | traversal.append(cur.val) 40 | stack.append(cur) 41 | cur = cur.left 42 | if len(stack)==0: 43 | break 44 | cur = stack.pop(-1) 45 | cur = cur.right 46 | return traversal 47 | 48 | 49 | tree = BinarySearchTree() 50 | nodes = [6,8,7,9,4,3,5] 51 | for i in nodes: 52 | tree.insert(i) 53 | traversal = preorder(tree.root) 54 | print(*traversal) -------------------------------------------------------------------------------- /Level 1/String/Check if one string is permutation of the other or not.py: -------------------------------------------------------------------------------- 1 | def isPermutation1(str1,str2): 2 | str1 = list(str1) 3 | str2 = list(str2) 4 | str1.sort() 5 | str2.sort() 6 | if str1==str2: 7 | return True 8 | return False 9 | 10 | str1 = 'abc' 11 | str2 = 'bacd' 12 | flag = isPermutation1(str1,str2) 13 | print(flag) 14 | 15 | 16 | def isPermutation2(str1,str2): 17 | count1 = {} 18 | count2 = {} 19 | for i in str1: 20 | if i in count1: 21 | count1[i]=count1[i]+1 22 | else: 23 | count1[i]=1 24 | for i in str2: 25 | if i in count2: 26 | count2[i]=count2[i]+1 27 | else: 28 | count2[i]=1 29 | 30 | for i in list(set(str1+str2)): 31 | if i not in count1 or i not in count2 or count1[i]!=count2[i]: 32 | return False 33 | 34 | return True 35 | 36 | str1 = 'abc' 37 | str2 = 'acbd' 38 | flag = isPermutation2(str1,str2) 39 | print(flag) 40 | 41 | def isPermutation3(str1,str2): 42 | count1 = {} 43 | for i in str1: 44 | if i in count1: 45 | count1[i]=count1[i]+1 46 | else: 47 | count1[i]=1 48 | for i in str2: 49 | if i in count1: 50 | count1[i]=count1[i]-1 51 | else: 52 | count1[i]=1 53 | 54 | for i,j in count1.items(): 55 | if j!=0: 56 | return False 57 | return True 58 | 59 | 60 | str1 = 'abc' 61 | str2 = 'bacd' 62 | flag = isPermutation3(str1,str2) 63 | print(flag) -------------------------------------------------------------------------------- /Level 1/Linked List/Doubly Linked List/Insertion doubly Linked List at middle.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.val = data 4 | self.next = None 5 | self.prev = None 6 | 7 | class LinkedList: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def insertAtStart(self,data): 12 | newNode = Node(data) 13 | if self.head==None: 14 | self.head = newNode 15 | else: 16 | self.head.prev = newNode 17 | newNode.next = self.head 18 | self.head = newNode 19 | 20 | def print(self): 21 | cur = self.head 22 | while cur!=None: 23 | print(cur.val,end=" ") 24 | cur = cur.next 25 | print() 26 | 27 | def insertAtMiddle(self,data,pos): 28 | newNode = Node(data) 29 | store = pos.next 30 | pos.next = newNode 31 | newNode.prev = pos 32 | newNode.next = store 33 | store.prev = newNode 34 | 35 | def search(self,key): 36 | cur = self.head 37 | keyNode = None 38 | while cur!=None: 39 | if cur.val == key: 40 | keyNode = cur 41 | break 42 | cur = cur.next 43 | return keyNode 44 | 45 | l = LinkedList() 46 | nodes_val = [1,2,3,4,5] 47 | for i in nodes_val: 48 | l.insertAtStart(i) 49 | l.print() #=> 5 4 3 2 1 50 | posValue = 3 51 | posNode = l.search(posValue) 52 | data = 10 53 | l.insertAtMiddle(data,posNode) 54 | l.print() #=> 5 4 3 10 2 1 --------------------------------------------------------------------------------