├── Arrays ├── Add-one-to-number.py ├── BubbleSort.py ├── Count-The-Triplets.py ├── Counting-elements-in-two-arrays.py ├── Find-Duplicate-in-Array.py ├── FlipArrayBits.py ├── Halloween-Sale.py ├── Hotel-Booking-Possible.py ├── Largest-Number.py ├── MAx-Non-Negative-Subarray.py ├── MaxAbsDifference.py ├── MaxSumContiguousSubarray.py ├── Maximum-Weight-Difference.py ├── Maximum-unsorted-array.py ├── MinStepsInInfiniteGrid.py ├── Noble-integers.py ├── Pairs-With-Sum-S.py ├── Pascal_triangle.py ├── Positive-And-Negative-Elements.py ├── Rotate-matrix.py ├── Set-Matrix-Zeroes.py ├── Spiral-Order-Matrix -II.py ├── Sum-Of-Lengths-Of-Non-Overlapping-Subarray.py ├── Triplet-with-given-sum-in-range.py ├── array-Rotations.py ├── find-permutations.py ├── firstMissinginteger.py ├── kth-row-of-pascals-triangle.py ├── max_distance.py ├── maximum-consecutive-gap.py ├── merge_sort.py ├── minAbsDiff.py ├── neigh.py ├── repeat-and-missing-number-array.py ├── sanjay's-new-job.py ├── spiralOrderMatrix.py ├── triplet_family.py └── wave-array.py ├── Backtracking ├── Combination-sum.py ├── Recursive-Digit-sum.py ├── The-Power-Sum.py ├── generate-all-parenthesis.py ├── kth-PermutationSequence.py ├── letterPhone.py └── permutations.py ├── Binary-Search ├── Binary-Search.py ├── Find-Duplicates.py ├── Implement-Power-Function.py ├── Matrix-Search.py ├── Matrix-median.py ├── Median-of-array.py ├── Painter's-partition-problem.py ├── Rotated-Array-search.py ├── Rotated-Array.py ├── Search-for-a-range.py ├── Square-root-of-integer.py └── sorted-insert-position.py ├── Bit-Manipulation ├── Min-XOR-Value.py ├── Power-of-2.py ├── Xor-upto-n.py ├── divide-integers.py ├── number-of-1-bits.py ├── reverseBit.py └── single-number.py ├── Doublylinkedlist ├── DLL_deletion.py ├── DLL_insertion.py ├── DLL_reverse.py ├── DLLfullsamplecode.py └── introduction ├── Dynamic-Programming ├── Best-Introduction.txt ├── CoinChange.py ├── DP-memoization-Technique.py ├── DP-tabulation-technique.py ├── Fibonacci-number.py ├── LengthOfLongestBitonicSubsequence.py ├── Longest-increasing-subsequence.py ├── LongestCommonSubsequence.py ├── LongestPalindromeSubsequence.py ├── Word-break.py ├── interleavingString.py ├── longestIncreasingSubsequence.py └── longestValidParentheses.py ├── Graph ├── DirectedBFS.py ├── UndirectedDFS.py └── number-of-islands.py ├── Greedy ├── InterleavingStrings.py ├── bulbs.py ├── gas-Station.py ├── highestProduct.py ├── majorityElement.py └── seats.py ├── Hashing ├── 4-sum.py └── longest-substring-without-repeat.py ├── LINKEDLIST ├── AddTwoLinkedList.py ├── LL_DELETION.py ├── LL_INSERTION.py ├── LL_INTRO.py ├── LL_LENGTH.py ├── LL_MERGE.py ├── LL_MERGEPOINT ├── LL_REVERSE.py ├── LL_TRAVERSAL.py ├── LL_compare.py ├── LL_cycledetection.py ├── LL_detectloops ├── LL_nodevalue.py ├── LL_rotate.py ├── Nth-Node-From-Last.py ├── ll_addNo.py ├── ll_mergeSort.py ├── ll_removeLoop.py ├── ll_removeloop2.py ├── ll_start.py └── ll_swapping.py ├── LinkedList ├── Add-LinkedList-as-no.py ├── Deleting-node-in-O(1).py ├── List-Cycle.py ├── Merge-Lists.py ├── Palindrome-List.py ├── Remove-Duplicates-ii.py ├── Remove-Duplicates.py ├── Remove-Nth-Node.py ├── Reorder-List.py ├── Reverse-LinkedList-ii.py ├── Rotate-List.py ├── Sort-List.py └── Swap-List-nodes-in-pairs.py ├── Math ├── Binary-Representation.py ├── DigitLCM.py ├── FizzBuzz.py ├── Greates-common-divisor.py ├── Grid-unique-paths.py ├── Horner-Method-Polynomial-Evaluation.py ├── MagicNumber.py ├── Max-GCD-Pair.py ├── N-as-max-composite-no.py ├── Palindrome-Integer.py ├── Power-Of-Two-Integers.py ├── Prime-Numbers.py ├── Prime-Sum.py ├── Print-Series.py ├── Rearrange-Array.py ├── Sort-An-array-of-0_1.py ├── Sorted-Permutation-Rank.py ├── Sum-of-pairwise-hamming-distance.py ├── Sum_of_Multiples.py ├── Verify-Prime.py ├── excel-column-number.py ├── largest-coprime-divisor.py ├── primeNumberDifference.py ├── reverse-integer.py └── sorted-permutations-rank-with-repeats.py ├── Matrix └── Print-Matrix-Z-Form.py ├── README.md ├── Stack ├── Balanced-Expression.py ├── Equal-Stack.py ├── Introduction ├── Introduction.py ├── Largest-Stack.py ├── Queue-using-two-stack.py ├── Stack Implementation.py ├── evaluateExpression.py ├── implementing two stack.py ├── infixToPostfix.py ├── min-stack.py ├── nearest-smaller-element.py ├── redundantBraces.py ├── reverse_string.py ├── rpn.py └── simplifydirectoryPath.py ├── String ├── Add-binary-strings.py ├── Atoi.py ├── Count-and-Say.py ├── Implement-StrStr.py ├── Integer-To-Roman.py ├── Justified-text.py ├── KMP-Algo.py ├── Length-of-last-word.py ├── Longest-Common-Prefix.py ├── Longest-Palindrome-substring.py ├── Palindrome-String.py ├── Power-of-2.py ├── Reverse-Strings.py ├── Roman-To-Integer.py ├── Searching-word-in-2D-matrix.py ├── Valid-Number.py ├── Valid-ip-address.py ├── addBinaryString.py ├── compare-version-numbers.py └── minimum-characters-required-to-make-a-string-palindrome.py ├── Tree ├── BST-Insertion.py ├── Binary-Search-Tree-Search.py ├── Print-Binary-Tree-in-Vertical-order.py ├── Tree-Traversal.py ├── ZigzagLevelOrderTraversal.py ├── balanced-binary-tree.py ├── inOrderTraversal.py └── level-order-traversal.py └── Two Pointers ├── 3Sum.py ├── 3SumZero.py ├── Counting-Triangles.py ├── Intersection-of arrays.py ├── Intersection.py ├── Maxseries1s.py ├── Merge-Two-Sorted-Lists.py ├── MinAbsDiff.py ├── Remove-Duplicates-2.py ├── RemoveDuplicates.py ├── RemoveElements.py ├── array-3-pointers.py └── container-with-most-water.py /Arrays/Add-one-to-number.py: -------------------------------------------------------------------------------- 1 | #Given a non-negative number represented as an array of digits, 2 | 3 | #add 1 to the number ( increment the number represented by the digits ). 4 | 5 | #The digits are stored 6 | #such that the most significant digit is at the head of the list. 7 | def plusOne(self, arr): 8 | while(arr[0]==0)and len(arr)>1: 9 | del(arr[0]) 10 | if arr[0]==0 and len(arr)==1: 11 | arr[0]=1 12 | return arr 13 | i=len(arr)-1 14 | carry=1 15 | while True: 16 | value=arr[i]+carry 17 | if value>=10: 18 | arr[i]=value%10 19 | carry=value//10 20 | else: 21 | arr[i]=value 22 | break 23 | if i==0: 24 | arr.insert(0,carry) 25 | break 26 | i-=1 27 | return arr 28 | -------------------------------------------------------------------------------- /Arrays/BubbleSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Bubble sort is a example of sorting algorithm . In this method we at first compare the data element in the first position with the second position and arrange them in desired order.Then we compare the data element with with third data element and arrange them in desired order. The same process continuous until the data element at second last and last position 3 | ''' 4 | def bubbleSort(arr,n): 5 | for i in range(0,n): 6 | for j in range(0,n): 7 | if arr[j]>arr[i]: 8 | arr[i], arr[j] = arr[j], arr[i] 9 | return arr 10 | 11 | arr = [3,2,6,4,1] 12 | print bubbleSort(arr,5) 13 | -------------------------------------------------------------------------------- /Arrays/Count-The-Triplets.py: -------------------------------------------------------------------------------- 1 | #Given an array of distinct integers. 2 | #The task is to count all the triplets 3 | #such that sum of two elements equals the third element. 4 | #Complexity O(n^2) 5 | def findTriplet(arr): 6 | arr.sort() 7 | n = len(arr) 8 | i = n-1 9 | count = 0 10 | while(i>=0): 11 | j=0 12 | k=i-1 13 | if (arr[i]==arr[j]+arr[k]): 14 | count +=1 15 | elif (arr[i]>arr[j]+arr[k]): 16 | j +=1 17 | else: 18 | k -=1 19 | i=i-1 20 | 21 | return count 22 | 23 | arr = [5,32,1,7,10,50,19,21,2] 24 | print findTriplet(arr) 25 | -------------------------------------------------------------------------------- /Arrays/Counting-elements-in-two-arrays.py: -------------------------------------------------------------------------------- 1 | #Given two unsorted arrays arr1[] and arr2[]. 2 | #They may contain duplicates. 3 | #For each element in arr1[] count elements 4 | #less than or equal to it in array arr2[]. 5 | #complexity O(n) 6 | def binary_search(arr,n,x): 7 | l=0 8 | h=n-1 9 | while(l<=h): 10 | mid = (l+h)/2 11 | if arr[mid]>x: 12 | h=mid-1 13 | else: 14 | l=mid+1 15 | #required index 16 | return h 17 | def countElements(arr1,arr2,m,n): 18 | arr2.sort() 19 | for i in range(m): 20 | #Last index of largest element smaller than or equal to x 21 | index = binary_search(arr2,n,arr1[i]) 22 | 23 | print index+1 24 | 25 | arr1 = [1,2,3,4,7,9] 26 | arr2 = [0,1,2,1,1,4] 27 | m=len(arr1) 28 | n=len(arr2) 29 | countElements(arr1, arr2, m, n) 30 | -------------------------------------------------------------------------------- /Arrays/Find-Duplicate-in-Array.py: -------------------------------------------------------------------------------- 1 | #Given a read only array of n + 1 integers between 1 and n, 2 | #find one number that repeats in linear time using less than O(n) space 3 | #and traversing the stream sequentially O(1) times 4 | def repeatedNumber(self, A): 5 | 6 | A = list(A) 7 | A.sort() 8 | 9 | for i in range(len(A)-1): 10 | if A[i+1] - A[i] !=1: 11 | return A[i] 12 | return -1 13 | -------------------------------------------------------------------------------- /Arrays/FlipArrayBits.py: -------------------------------------------------------------------------------- 1 | #You are given a binary string(i.e. with characters 0 and 1) S 2 | #consisting of characters S1, S2, …, SN. 3 | #In a single operation, you can choose two indices L and R 4 | #such that 1 ≤ L ≤ R ≤ N and flip the characters SL, SL+1, …, SR. 5 | #By flipping, we mean change character 0 to 1 and vice-versa. 6 | 7 | #Your aim is to perform ATMOST one operation 8 | #such that in final string number of 1s is maximised. 9 | #If you don’t want to perform the operation, return an empty array. 10 | #Else, return an array consisting of two elements denoting L and R. 11 | #If there are multiple solutions, 12 | #return the lexicographically smallest pair of L and R. 13 | 14 | def flip(A): 15 | start =0 16 | ans = None 17 | diff = 0 18 | max_diff = 0 19 | 20 | for i,a in enumerate(A): 21 | diff +=(1 if a is '0' else -1) 22 | 23 | if diff<0: 24 | diff = 0 25 | start = i+1 26 | continue 27 | 28 | if diff > max_diff: 29 | max_diff = diff 30 | ans = [start,i] 31 | 32 | if ans is None: 33 | return [] 34 | 35 | return map(lambda x:x +1,ans) 36 | -------------------------------------------------------------------------------- /Arrays/Halloween-Sale.py: -------------------------------------------------------------------------------- 1 | ''' 2 | You wish to buy video games from the famous online video game store Mist. 3 | 4 | Usually, all games are sold at the same price, p dollars. However, they are planning to have the seasonal Halloween Sale next month in which you can buy games at a cheaper price. Specifically, the first game you buy during the sale will be sold at p dollars, but every subsequent game you buy will be sold at exactly d dollars less than the cost of the previous one you bought. This will continue until the cost becomes less than or equal to m dollars, after which every game you buy will cost m dollars each. 5 | 6 | For example, if p=20,d=3 and m=6 , then the following are the costs of the first 11 games you buy, in order: 7 | 20,17,14,11,8,6,6,6,6,6,6 8 | 9 | You have s dollars in your Mist wallet. How many games can you buy during the Halloween Sale? 10 | ''' 11 | import sys 12 | 13 | def howManyGames(p, d, m, s): 14 | # Return the number of games you can buy 15 | sum_ = p 16 | c = 1 17 | if p > s: 18 | return 0 19 | while (sum_ + p <= s): 20 | if p-d >= m: 21 | p = p-d 22 | sum_ += p 23 | c +=1 24 | else: 25 | p = m 26 | sum_ += p 27 | c += 1 28 | return c 29 | 30 | if __name__ == "__main__": 31 | p, d, m, s = raw_input().strip().split(' ') 32 | p, d, m, s = [int(p), int(d), int(m), int(s)] 33 | answer = howManyGames(p, d, m, s) 34 | print answer 35 | -------------------------------------------------------------------------------- /Arrays/Hotel-Booking-Possible.py: -------------------------------------------------------------------------------- 1 | """A hotel manager has to process N advance bookings of rooms for the next season. 2 | His hotel has K rooms. Bookings contain an arrival date and a departure date. 3 | He wants to find out whether there are enough rooms in the hotel to satisfy the demand. 4 | Write a program that solves this problem in time O(N log N) .""" 5 | def hotelBooking(arrival,depart,k): 6 | events = [(t,1) for t in arrival] + [(t,0) for t in depart] 7 | events.sort() 8 | guests = 0 9 | for event in events: 10 | if event[1] == 1: 11 | guests +=1 12 | else: 13 | guests -=1 14 | if guests > k: 15 | return 0 16 | return 1 17 | 18 | arrival = [1,3,5] 19 | depart = [2,6,8] 20 | k=1 21 | print hotelBooking(arrival,depart,k) 22 | -------------------------------------------------------------------------------- /Arrays/Largest-Number.py: -------------------------------------------------------------------------------- 1 | #Given a list of non negative integers, 2 | #arrange them such that they form the largest number. 3 | def largestNumber(self, num): 4 | # Define customized compare function for sorting 5 | def compare(n1, n2): 6 | if n1+n2 > n2+n1: 7 | return 1 8 | elif n1+n2 < n2+n1: 9 | return -1 10 | else: 11 | return 0 12 | 13 | num_str = [str(n) for n in num] 14 | res = "" 15 | 16 | # Sorting according to customized function 17 | for n in reversed( sorted(num_str,cmp=compare) ): 18 | res += n 19 | 20 | # Remove unnecessary zeros in head 21 | res_list = list(res) 22 | i = 0 23 | while res_list[i] == '0' and i != len(res)-1: 24 | i += 1 25 | res_list = res_list[i:] 26 | 27 | return ''.join( res_list) 28 | -------------------------------------------------------------------------------- /Arrays/MAx-Non-Negative-Subarray.py: -------------------------------------------------------------------------------- 1 | #Find out the maximum sub-array of non negative numbers from an array. 2 | #The sub-array should be continuous. 3 | #That is, a sub-array created by choosing the second and fourth element 4 | #and skipping the third element is invalid. 5 | 6 | #Maximum sub-array is defined in terms of the sum of the elements in the sub-array. 7 | #Sub-array A is greater than sub-array B if sum(A) > sum(B). 8 | 9 | 10 | def LongestSum(arr): 11 | currSum = currStart = currLength = maxSum = maxStart = maxLength = 0 12 | for i in range(len(arr)): 13 | if arr[i]<0: 14 | if (currSum>maxSum) or (currSum == maxSum and currLength>maxLength): 15 | maxSum = currSum 16 | maxLength = currLength 17 | maxStart = currStart 18 | currStart = i+1 19 | currSum = currLength =0 20 | else: 21 | currSum += arr[i] 22 | currLength +=1 23 | 24 | if (currSum>maxSum) or (currSum == maxSum and currLength>maxLength): 25 | maxSum = currSum 26 | maxLength = currLength 27 | maxStart = currStart 28 | return arr[maxStart:maxStart+maxLength] 29 | #Main Driver Program 30 | arr=[1,2,5,-7,2,3] 31 | print LongestSum(arr) 32 | -------------------------------------------------------------------------------- /Arrays/MaxAbsDifference.py: -------------------------------------------------------------------------------- 1 | #You are given an array of N integers, A1, A2 ,…, AN. 2 | #Return maximum value of f(i, j) for all 1 ≤ i, j ≤ N. 3 | #f(i, j) is defined as |A[i] - A[j]| + |i - j|, 4 | #where |x| denotes absolute value of x. 5 | #For ex- 6 | #A=[1, 3, -1] 7 | 8 | #f(1, 1) = f(2, 2) = f(3, 3) = 0 9 | #f(1, 2) = f(2, 1) = |1 - 3| + |1 - 2| = 3 10 | #f(1, 3) = f(3, 1) = |1 - (-1)| + |1 - 3| = 4 11 | #f(2, 3) = f(3, 2) = |3 - (-1)| + |2 - 3| = 5 12 | 13 | #So, we return 5. 14 | from sys import maxint 15 | def maxArr(arr): 16 | 17 | max1 = -maxint -1 18 | max2 = -maxint -1 19 | max3 = -maxint -1 20 | max4 = -maxint -1 21 | ans = -maxint -1 22 | 23 | for i in range(0,len(arr)): 24 | max1 = max(max1,arr[i]+i) 25 | max2 = max(max2,-arr[i]+i) 26 | max3 = max(max3,arr[i]-i) 27 | max4 = max(max4,-arr[i]-i) 28 | 29 | min1 = min(min1,A[i] + i) 30 | min2 = min(min2,A[i] - i) 31 | min3 = min(min3,-A[i]+i) 32 | min4 = min(min4,-A[i]-i) 33 | 34 | ans = max(ans,max1-arr[i]-i) 35 | ans = max(ans,max2+arr[i]-i) 36 | ans = max(ans,max3-arr[i]+i) 37 | ans = max(ans,max4+arr[i]+i) 38 | return ans 39 | -------------------------------------------------------------------------------- /Arrays/MaxSumContiguousSubarray.py: -------------------------------------------------------------------------------- 1 | #Find the contiguous subarray within an array 2 | #(containing at least one number) which has the largest sum. 3 | from sys import maxint 4 | def maxSubArray(self, a): 5 | max_so_far = -maxint - 1 6 | max_ending_here = 0 7 | 8 | for i in range(0, len(a)): 9 | max_ending_here = max_ending_here + a[i] 10 | if (max_so_far < max_ending_here): 11 | max_so_far = max_ending_here 12 | 13 | if max_ending_here < 0: 14 | max_ending_here = 0 15 | return max_so_far 16 | -------------------------------------------------------------------------------- /Arrays/Maximum-Weight-Difference.py: -------------------------------------------------------------------------------- 1 | #Given an array. 2 | #The task is to choose K numbers from the array 3 | #such that the absolute difference between the sum of chosen numbers 4 | #and the sum of remaining numbers is maximum. 5 | 6 | sum1=sum2=0 7 | arr = [8,4,5,2,10] 8 | k = 2 9 | n=len(arr) 10 | arr=sorted(arr) 11 | 12 | if k0 and arr[r] == s[r]: 14 | r -=1 15 | 16 | if arr == s: 17 | return [-1] 18 | else: 19 | return [l,r] 20 | 21 | arr = [1,3,2,4,5] 22 | print unsorted(arr) 23 | -------------------------------------------------------------------------------- /Arrays/MinStepsInInfiniteGrid.py: -------------------------------------------------------------------------------- 1 | #You are in an infinite 2D grid where you can move in any of the 8 directions : 2 | #(x,y) to 3 | # (x+1, y), 4 | # (x - 1, y), 5 | # (x, y+1), 6 | # (x, y-1), 7 | # (x-1, y-1), 8 | # (x+1,y+1), 9 | # (x-1,y+1), 10 | # (x+1,y-1) 11 | #You are given a sequence of points and the order in which you need to cover the points. 12 | #Give the minimum number of steps in which you can achieve it. 13 | #You start from the first point. 14 | def coverPoints(self, X, Y): 15 | s1 = len(X) 16 | s2 = len(Y) 17 | ans = 0 18 | for i in range(1,s1): 19 | if abs(X[i]-X[i-1])< abs(Y[i]-Y[i-1]): 20 | ans =ans+abs(Y[i]-Y[i-1]) 21 | 22 | else: 23 | ans = ans+abs(X[i]-X[i-1]) 24 | return ans 25 | -------------------------------------------------------------------------------- /Arrays/Noble-integers.py: -------------------------------------------------------------------------------- 1 | #Given an integer array, 2 | #find if an integer p exists in the array such that the number of integers greater than p in the array equals to p 3 | #If such an integer is found return 1 else return -1. 4 | def solve(self, A): 5 | inputSize = len(A) 6 | A.sort() 7 | start = A[0] 8 | for i in xrange(inputSize): 9 | if (start != A[i]) and (start == (inputSize - i)): 10 | return 1 11 | start = A[i] 12 | if start == 0: 13 | return 1 14 | return -1 15 | -------------------------------------------------------------------------------- /Arrays/Pairs-With-Sum-S.py: -------------------------------------------------------------------------------- 1 | s=10 2 | arr = [1,3,7,4,6,9] 3 | for i in range(len(arr)): 4 | if (s-arr[i]) in arr: 5 | print arr[i],arr[arr.index(s-arr[i])] 6 | -------------------------------------------------------------------------------- /Arrays/Pascal_triangle.py: -------------------------------------------------------------------------------- 1 | #Given numRows, generate the first numRows of Pascal’s triangle. 2 | 3 | #Pascal’s triangle : 4 | #To generate A[C] in row R, sum up A’[C] and A’[C-1] from previous row R - 1. 5 | 6 | def generate(n): 7 | arr = [[0 for _ in range(n) ] for _ in range(n)] 8 | for line in range(0,n): 9 | for i in range(0,line+1): 10 | if line == i or i == 0: 11 | arr[line][i] = 1 12 | else: 13 | arr[line][i] = arr[line-1][i-1]+arr[line-1][i] 14 | 15 | for i in arr: 16 | for j in arr: 17 | if 0 in j: 18 | j.remove(0) 19 | return arr 20 | 21 | n=5 22 | print generate(n) 23 | -------------------------------------------------------------------------------- /Arrays/Positive-And-Negative-Elements.py: -------------------------------------------------------------------------------- 1 | #Given an array containing equal number of positive 2 | #and negative elements, arrange the array such that every positive element 3 | #is followed by a negative element. 4 | #Complexity O(n) 5 | 6 | t=int(raw_input()) 7 | for i in range(t): 8 | n = int(raw_input()) 9 | arr = map(int,raw_input()) 10 | arr.sort() 11 | c = 0 12 | lis = [] 13 | for i in range(len(arr)): 14 | if arr[i]<0: 15 | c +=1 16 | else: 17 | break 18 | 19 | right = c 20 | left = c-1 21 | while left>=0 or right =0): 10 | j = 0 11 | k = i-1 12 | if i == j or k == j: 13 | return 0 14 | 15 | elif arr[i]+arr[j]+arr[k]>1 and arr[i]+arr[j]+arr[k]<2: 16 | print arr[i]+arr[j]+arr[k] 17 | elif arr[i]+arr[j]+arr[k]>=2: 18 | k -=1 19 | else: 20 | j +=1 21 | i -=1 22 | 23 | return 0 24 | 25 | #Method 2 26 | def solve(self, A): 27 | A = sorted(A) 28 | 29 | i = 0 30 | j = len(A)-1 31 | while i < j-1: 32 | s = float(A[i]) + float(A[j]) 33 | if i + 1 < len(A) - 1: 34 | three = s + float(A[i+1]) 35 | if three > 1 and three < 2: 36 | return 1 37 | elif three < 1: 38 | i += 1 39 | else: 40 | j -= 1 41 | return 0 42 | -------------------------------------------------------------------------------- /Arrays/array-Rotations.py: -------------------------------------------------------------------------------- 1 | Given an array of n integers and a number, k, perform k left rotations on the array. Then print the updated array as a single line of space-separated integer 2 | def array_left_rotation(a, n, k): 3 | arr=[0]*n 4 | for i in range(n): 5 | 6 | arr[i%n] = a[(i+k)%n] 7 | return arr 8 | 9 | 10 | n, k = map(int, raw_input().strip().split(' ')) 11 | a = map(int, raw_input().strip().split(' ')) 12 | answer = array_left_rotation(a, n, k); 13 | print ' '.join(map(str,answer)) 14 | -------------------------------------------------------------------------------- /Arrays/find-permutations.py: -------------------------------------------------------------------------------- 1 | """Given a positive integer n and a string s consisting only of letters D or I, 2 | you have to find any permutation of first n positive integer that satisfy the given input string. 3 | 4 | D means the next number is smaller, while I means the next number is greater.""" 5 | def findPerm(arr, b): 6 | ans = range(1,b+1) 7 | cnt = 0 8 | for i in range(len(arr)): 9 | if arr[i] == "D": 10 | cnt +=1 11 | else: 12 | ans[i-cnt:i+1] = ans[i-cnt:i+1][::-1] 13 | cnt =0 14 | if arr[-1] == "D": 15 | 16 | ans[len(arr) - cnt:len(arr) +1] = ans[len(arr) - cnt:len(arr)+1][::-1] 17 | return ans 18 | -------------------------------------------------------------------------------- /Arrays/firstMissinginteger.py: -------------------------------------------------------------------------------- 1 | #Give an unsorted integer array, find the first missing positive integer 2 | def firstMissingPositive(arr): 3 | length = len(arr) 4 | maximum = max(arr) 5 | 6 | if maximum < 0 : 7 | return 1 8 | value = [None]*max(maximum,length) 9 | 10 | for i in arr: 11 | if i > 0: 12 | value[i-1] = 1 13 | 14 | for i,data in enumerate(value): 15 | if data == None: 16 | return i+1 17 | 18 | return i+2 19 | 20 | arr = [1,2,0] 21 | print firstMissingPositive(arr) 22 | -------------------------------------------------------------------------------- /Arrays/kth-row-of-pascals-triangle.py: -------------------------------------------------------------------------------- 1 | #Given an index k, return the kth row of the Pascal’s triangle. 2 | 3 | #Pascal’s triangle : To generate A[C] in row R, sum up A’[C] and A’[C-1] 4 | #from previous row R - 1. 5 | 6 | def getRow(self, A): 7 | 8 | arr = [[0 for _ in range(A+1) ] for _ in range(A+1)] 9 | for line in range(0,A+1): 10 | for i in range(0,line+1): 11 | if line == i or i == 0: 12 | arr[line][i] = 1 13 | else: 14 | arr[line][i] = arr[line-1][i-1]+arr[line-1][i] 15 | 16 | for i in arr: 17 | for j in arr: 18 | if 0 in j: 19 | j.remove(0) 20 | return arr[A] 21 | -------------------------------------------------------------------------------- /Arrays/max_distance.py: -------------------------------------------------------------------------------- 1 | #Given an array A of integers, find the maximum of j - i subjected to the constraint of A[i] <= A[j]. 2 | 3 | #If there is no solution possible, return -1. 4 | 5 | from sys import maxint 6 | def maximumGap(arr): 7 | n = len(arr) 8 | start = 0 9 | end = n-1 10 | maximum = -maxint-1 11 | if n == 0 or n==1: 12 | return 0 13 | 14 | while (start < end): 15 | if arr[end] >= arr[start]: 16 | prev_max = end -start 17 | if maximum < prev_max: 18 | maximum = prev_max 19 | start +=1 20 | else: 21 | end -=1 22 | return maximum 23 | -------------------------------------------------------------------------------- /Arrays/maximum-consecutive-gap.py: -------------------------------------------------------------------------------- 1 | """Given an unsorted array, f 2 | ind the maximum difference between the successive elements in its sorted form. 3 | 4 | Try to solve it in linear time/space.""" 5 | 6 | def maximumGap(arr): 7 | 8 | arr.sort() 9 | n = len(arr) 10 | if n<= 2: 11 | return 0 12 | maximum = 0 13 | start_index = 0 14 | for i in range(1,n): 15 | if arr[i]-arr[start_index] > maximum: 16 | maximum = arr[i] - arr[start_index] 17 | start_index += 1 18 | else: 19 | start_index += 1 20 | return maximum 21 | 22 | arr = [1, 10, 5] 23 | print maximumGap(arr) 24 | -------------------------------------------------------------------------------- /Arrays/merge_sort.py: -------------------------------------------------------------------------------- 1 | def merge(arr, s1, s2): 2 | 3 | i=j=0 4 | while i+j < len(arr): 5 | if j == len(s2) or (i=x: 18 | 19 | print i[0] , i[1] 20 | -------------------------------------------------------------------------------- /Arrays/spiralOrderMatrix.py: -------------------------------------------------------------------------------- 1 | #Given a matrix of m * n elements (m rows, n columns), 2 | #return all elements of the matrix in spiral order. 3 | def spiralOrder(self, A): 4 | result = [] 5 | m = len(A) 6 | n = len(A[0]) 7 | ## Actual code to populate result 8 | t=0 9 | b=m-1 10 | l=0 11 | r=n-1 12 | dir = 0 13 | while (t<=b and l<=r): 14 | if dir ==0: 15 | for i in range(l,r+1): 16 | result.append(A[t][i]) 17 | t =t+1 18 | dir = 1 19 | elif (dir ==1): 20 | for i in range(t,b+1): 21 | result.append(A[i][r]) 22 | r=r-1 23 | dir = 2 24 | elif (dir == 2): 25 | for i in range(r,l-1,-1): 26 | result.append(A[b][i]) 27 | b=b-1 28 | dir = 3 29 | elif (dir ==3): 30 | for i in range(b,t-1,-1): 31 | result.append(A[i][l]) 32 | l=l+1 33 | dir =0 34 | else: 35 | print "Error" 36 | return result 37 | -------------------------------------------------------------------------------- /Arrays/triplet_family.py: -------------------------------------------------------------------------------- 1 | 2 | arr = [5,32,1,7,10,50,19,21,0] 3 | var = False 4 | for i in range(len(arr)): 5 | for j in range(1,len(arr)): 6 | if (arr[i]+arr[j]) in arr: 7 | var= True 8 | 9 | if var: 10 | print "1" 11 | else: 12 | print "-1" 13 | -------------------------------------------------------------------------------- /Arrays/wave-array.py: -------------------------------------------------------------------------------- 1 | #Given an array of integers, 2 | #sort the array into a wave like array and return it, 3 | #In other words, arrange the elements into a sequence 4 | #such that a1 >= a2 <= a3 >= a4 <= a5..... 5 | def solve(arr): 6 | arr.sort() 7 | n = len(arr) 8 | array =[0]*len(arr) 9 | for i in range(0,n,2): 10 | 11 | if i ==n-1: 12 | array[i] = arr[i] 13 | else: 14 | array[i+1] = arr[i] 15 | 16 | for j in range(1,n,2): 17 | array[j-1] = arr[j] 18 | 19 | return array 20 | 21 | arr = [5,1,3,2,4] 22 | print solve(arr) 23 | -------------------------------------------------------------------------------- /Backtracking/Combination-sum.py: -------------------------------------------------------------------------------- 1 | from itertools import groupby 2 | def combinationSum(self,arr, target): 3 | res = [] 4 | arr = sorted(arr) 5 | def dfs(remain, stack): 6 | if remain == 0: 7 | res.append(stack) 8 | return 9 | 10 | for item in arr: 11 | if item > remain: 12 | break 13 | if stack and item < stack[-1]: 14 | continue 15 | else: 16 | dfs(remain-item,stack + [item]) 17 | dfs(target, []) 18 | result = list(k for k,_ in groupby(res)) 19 | return result 20 | arr = [ 8, 10, 6, 11, 1, 16, 8 ] 21 | target = 28 22 | print combinationSum(arr,target) 23 | -------------------------------------------------------------------------------- /Backtracking/Recursive-Digit-sum.py: -------------------------------------------------------------------------------- 1 | ''' 2 | We define super digit of an integer x using the following rules: 3 | 4 | If x has only 1 digit, then its super digit is x. 5 | Otherwise, the super digit of x is equal to the super digit of the digit-sum of x. Here, digit-sum of a number is defined as the sum of its digits. 6 | 7 | ''' 8 | # Enter your code here. Read input from STDIN. Print output to STDOUT 9 | n, k = map(int, raw_input().split()) 10 | x = n*k % 9 11 | print x if x else 9 12 | -------------------------------------------------------------------------------- /Backtracking/The-Power-Sum.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Find the number of ways that a given integer X, can be expressed as the sum of N the power of unique, natural numbers. 3 | ''' 4 | def countWaysUtil(x, n, num): 5 | val = x - (num**n) 6 | if val == 0: 7 | return 1 8 | if val < 0: 9 | return 0 10 | return countWaysUtil(val, n, num + 1) + countWaysUtil(x, n, num+1) 11 | 12 | x = int(raw_input()) 13 | n = int(raw_input()) 14 | print countWaysUtil(x, n, 1) 15 | -------------------------------------------------------------------------------- /Backtracking/generate-all-parenthesis.py: -------------------------------------------------------------------------------- 1 | def generateParenthesis(n): 2 | ans = [] 3 | def backtrack(S = '', left = 0, right = 0): 4 | if len(S) == 2*n: 5 | ans.append(S) 6 | return 7 | if left < n: 8 | backtrack(S + '(',left+1, right) 9 | if right < left: 10 | backtrack(S + ')',left,right+1) 11 | backtrack() 12 | return ans 13 | print generateParenthesis(3) 14 | -------------------------------------------------------------------------------- /Backtracking/kth-PermutationSequence.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The set [1,2,3,…,n] contains a total of n! unique permutations. 3 | 4 | By listing and labeling all of the permutations in order, 5 | We get the following sequence (ie, for n = 3 ) : 6 | 7 | 1. "123" 8 | 2. "132" 9 | 3. "213" 10 | 4. "231" 11 | 5. "312" 12 | 6. "321" 13 | Given n and k, return the kth permutation sequence. 14 | 15 | For example, given n = 3, k = 4, ans = "231" 16 | ''' 17 | import math 18 | class Solution: 19 | # @param {integer} n 20 | # @param {integer} k 21 | # @return {string} 22 | def getPermutation(self, n, k): 23 | numbers = range(1, n+1) 24 | permutation = '' 25 | k -= 1 26 | while n > 0: 27 | n -= 1 28 | # get the index of current digit 29 | index, k = divmod(k, math.factorial(n)) 30 | permutation += str(numbers[index]) 31 | # remove handled number 32 | numbers.remove(numbers[index]) 33 | 34 | return permutation 35 | -------------------------------------------------------------------------------- /Backtracking/letterPhone.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.phone_map = { 4 | '0': ['0'], 5 | '1': ['1'], 6 | '2': ['a', 'b', 'c'], 7 | '3': ['d', 'e', 'f'], 8 | '4': ['g', 'h', 'i'], 9 | '5': ['j', 'k', 'l'], 10 | '6': ['m', 'n', 'o'], 11 | '7': ['p', 'q', 'r', 's'], 12 | '8': ['t', 'u', 'v'], 13 | '9': ['w', 'x', 'y', 'z'] 14 | } 15 | 16 | # @param A : string 17 | # @return a list of strings 18 | def letterCombinations(self, A): 19 | if len(A) == 0: 20 | return [] 21 | 22 | if A in self.phone_map: 23 | return self.phone_map[A] 24 | n = len(A) 25 | left_combos = self.letterCombinations(A[:n/2]) 26 | right_combos = self.letterCombinations(A[n/2:]) 27 | possible_combos = [left + right for left in left_combos for right in right_combos] 28 | self.phone_map[A] = possible_combos 29 | return possible_combos 30 | -------------------------------------------------------------------------------- /Backtracking/permutations.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | class Solution: 3 | # @param A : list of integers 4 | # @return a list of list of integers 5 | def permute(self, A): 6 | return map(list, permutations(A)) 7 | -------------------------------------------------------------------------------- /Binary-Search/Binary-Search.py: -------------------------------------------------------------------------------- 1 | def binarySearch(target,arr): 2 | floor_index = -1 3 | ceiling_index = len(arr) 4 | while floor_index + 1 < ceiling_index: 5 | distance = floor_index + ceiling_index 6 | half_distance = distance/2 7 | guess_index = floor_index + half_distance 8 | guess_value = arr[guess_index] 9 | if guess_value == target: 10 | return True 11 | if guess_value > target: 12 | ceiling_index = guess_index 13 | else: 14 | floor_index = guess_index 15 | return False 16 | -------------------------------------------------------------------------------- /Binary-Search/Find-Duplicates.py: -------------------------------------------------------------------------------- 1 | def findCount(arr,target): 2 | n = len(arr) 3 | floor_index = 0 4 | ceiling_index = n-1 5 | first_occurence = -1 6 | while floor_index < ceiling_index: 7 | mid = (floor_index + ceiling_index)/2 8 | if arr[mid] == target: 9 | first_occurence = mid 10 | high = mid-1 11 | elif arr[mid] > target: 12 | ceiling_index = mid-1 13 | else: 14 | floor_index = mid+1 15 | 16 | if first_occurence == -1: 17 | return 0 18 | 19 | floor_index = first_occurence 20 | high = n-1 21 | second_occurence = -1 22 | while floor_index < ceiling_index: 23 | mid = (floor_index + ceiling_index)/2 24 | if arr[mid] == target: 25 | second_occurence = mid 26 | low = mid + 1 27 | else: 28 | high = mid -1 29 | return second_occurence - first_occurence + 1 30 | 31 | ''' 32 | class Solution: 33 | # @param A : tuple of integers 34 | # @param B : integer 35 | # @return an integer 36 | def findCount(self, arr, x): 37 | 38 | def first(arr,low,high,x): 39 | 40 | if (high >= low): 41 | 42 | mid = (low+high)/2 43 | if (mid == 0 or x >arr[mid-1]) and arr[mid] == x: 44 | return mid 45 | elif x > arr[mid]: 46 | return first(arr,(mid+1),high,x) 47 | else: 48 | return first(arr,low,(mid-1),x) 49 | return 0 50 | def last(arr,low,high,x): 51 | 52 | if high >= low: 53 | mid = (low+high)/2 54 | if (mid == len(arr)-1 or x < arr[mid+1]) and arr[mid] == x: 55 | return mid 56 | elif x < arr[mid]: 57 | return last(arr,low,(mid-1),x) 58 | else: 59 | return last(arr,(mid+1),high,x) 60 | return 0 61 | 62 | i = first(arr,0,len(arr)-1,x) 63 | if i == 0: 64 | return i 65 | j = last(arr,i,len(arr)-1,x) 66 | return j-i+1 67 | 68 | ''' 69 | -------------------------------------------------------------------------------- /Binary-Search/Implement-Power-Function.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Implement pow(x, n) % d. 3 | 4 | In other words, given x, n and d, 5 | 6 | find (xn % d) 7 | 8 | Note that remainders on division cannot be negative. 9 | In other words, make sure the answer you return is non negative 10 | ''' 11 | def pow(self, x, n, d): 12 | result = 1 13 | base = x % d 14 | while n > 0: 15 | if n % 2 == 1: 16 | result = (result*base) % d 17 | n = n >> 1 18 | base = (base*base)%d 19 | return result%d 20 | -------------------------------------------------------------------------------- /Binary-Search/Matrix-Search.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Write an efficient algorithm that searches for a value in an m x n matrix. 3 | 4 | This matrix has the following properties: 5 | ->Integers in each row are sorted from left to right. 6 | ->The first integer of each row is greater than or equal to the last integer of the previous row. 7 | ''' 8 | def searchMatrix(self, arr, target): 9 | 10 | n = len(arr) 11 | 12 | if len(arr) == 1: 13 | if arr[0][0] == target: 14 | return 1 15 | else: 16 | return 0 17 | for i in arr: 18 | 19 | floor_index = 0 20 | ceiling_index = len(arr[0]) - 1 21 | while floor_index <=ceiling_index: 22 | mid = (floor_index + ceiling_index)/2 23 | if i[mid] == target: 24 | return 1 25 | elif i[mid] > target: 26 | ceiling_index = mid-1 27 | else: 28 | floor_index = mid + 1 29 | return 0 30 | -------------------------------------------------------------------------------- /Binary-Search/Matrix-median.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a N cross M matrix in which each row is sorted, find the overall median of the matrix. Assume N*M is odd. 3 | ''' 4 | class Solution: 5 | # @param A : list of list of integers 6 | # @return an integer 7 | def findMedian(self, matrix): 8 | 9 | lis = [] 10 | for i in range(len(matrix)): 11 | for j in range(len(matrix[0])): 12 | lis.append(matrix[i][j]) 13 | 14 | lis.sort() 15 | return lis[len(lis)/2] 16 | -------------------------------------------------------------------------------- /Binary-Search/Median-of-array.py: -------------------------------------------------------------------------------- 1 | ''' 2 | There are two sorted arrays A and B of size m and n respectively. 3 | 4 | Find the median of the two sorted arrays ( The median of the array formed by merging both the arrays ). 5 | 6 | The overall run time complexity should be O(log (m+n)). 7 | ''' 8 | 9 | class Solution: 10 | # @param A : tuple of integers 11 | # @param B : tuple of integers 12 | # @return a double 13 | def findMedianSortedArrays(self, A, B): 14 | m = len(A) 15 | n = len(B) 16 | if m > n: 17 | n,m = m,n 18 | A,B = B,A 19 | if m == 0: 20 | if n == 0: 21 | return 0 22 | if n%2: 23 | return B[n/2] 24 | else: 25 | return (B[n/2]+B[n/2-1])/2.0 26 | low = 0 27 | high = m 28 | while low <= high: 29 | i = (low+high)/2 30 | j = (m+n+1)/2-i 31 | if (j == 0 or i == m or B[j - 1] <= A[i]) and (i == 0 or j == n or A[i-1] <= B[j]): 32 | if (m+n)%2: 33 | if i == 0: 34 | return B[j-1] 35 | elif j == 0: 36 | return A[i-1] 37 | return max(A[i-1],B[j-1]) 38 | else: 39 | if i == 0: 40 | return (B[j-1] + min(A[i],B[j]))/2.0 41 | if j == 0: 42 | return (A[i-1] + min(A[i],B[j]))/2.0 43 | if i == m: 44 | return (max(A[i-1],B[j-1]) + B[j])/2.0 45 | if j == n: 46 | return (max(A[i-1],B[j-1]) + A[i])/2.0 47 | return (max(A[i-1],B[j-1]) + min(A[i],B[j]))/2.0 48 | elif (j == 0 or i == m or B[j - 1] > A[i]): 49 | low = i+1 50 | elif (i == 0 or j == n or A[i-1] > B[j]): 51 | high = i-1 52 | return -1 53 | 54 | -------------------------------------------------------------------------------- /Binary-Search/Painter's-partition-problem.py: -------------------------------------------------------------------------------- 1 | ''' 2 | You have to paint N boards of length {A0, A1, A2, A3 … AN-1}. There are K painters available and you are also given how much time a painter takes to paint 1 unit of board. You have to get this job done as soon as possible under the constraints that any painter will only paint contiguous sections of board. 3 | ''' 4 | def ppp(n,time,arr): 5 | def isPossible(t,c,a): 6 | summ = 0 7 | while a > 0 and len(c) > 0: 8 | if summ + c[-1] > t: 9 | summ = 0 10 | a -=1 11 | else: 12 | summ += c.pop() 13 | if len(c) == 0: 14 | return True 15 | else: 16 | return False 17 | 18 | x = max(arr) 19 | y = sum(arr) 20 | if len(arr) == 0: 21 | return 0 22 | if len(arr) == 1: 23 | return time*arr[0] 24 | prev = y 25 | while x < y: 26 | m = (x + y)/2 27 | if isPossible(m,arr[:],n): 28 | prev = m 29 | y = m - 1 30 | else: 31 | x = m + 1 32 | m = prev 33 | while isPossible(m-1,arr[:],n): 34 | m = m - 1 35 | return m*B % 1000003 36 | -------------------------------------------------------------------------------- /Binary-Search/Rotated-Array-search.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Suppose a sorted array is rotated at some pivot unknown to you beforehand. 3 | 4 | (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2 ). 5 | 6 | You are given a target value to search. If found in the array, return its index, otherwise return -1. 7 | 8 | You may assume no duplicate exists in the array. 9 | ''' 10 | def sortedarraySearch(arr): 11 | floor_index = 0 12 | ceiling_index = len(arr) - 1 13 | while floor_index < ceiling_index: 14 | mid = (floor_index + ceiling_index)/2 15 | if arr[mid] > ceiling_index: 16 | floor_index =mid + 1 17 | else: 18 | ceiling_index = mid - 1 19 | arr = arr[floor_index:] + arr[:floor_index] 20 | return arr 21 | 22 | def findIndex(arr,target): 23 | 24 | arr = sortedarraySearch(arr) 25 | floor_index = 0 26 | ceiling_index =len(arr)-1 27 | while floor_index < ceiling_index: 28 | mid = (floor_index + ceiling_index)/2 29 | if arr[mid] == target: 30 | return mid 31 | elif arr[mid] > target: 32 | ceiling_index = mid-1 33 | else: 34 | floor_index = mid + 1 35 | -------------------------------------------------------------------------------- /Binary-Search/Rotated-Array.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Suppose a sorted array A is rotated at some pivot unknown to you beforehand. 3 | 4 | (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). 5 | 6 | Find the minimum element. 7 | 8 | The array will not contain duplicates. 9 | ''' 10 | def findMin(arr): 11 | if len(arr) == 1: 12 | return arr[0] 13 | else: 14 | low = 0 15 | high = len(arr)-1 16 | mid = (low+high)/2 17 | if arr[mid] > arr[high]: 18 | return findMin(arr[mid+1:]) 19 | elif arr[mid] < arr[high]: 20 | return findMin(arr[:mid+1]) 21 | arr = [4,5,6,7,0,1,2] 22 | print findMin(arr) 23 | -------------------------------------------------------------------------------- /Binary-Search/Search-for-a-range.py: -------------------------------------------------------------------------------- 1 | '''Given a sorted array of integers, find the starting and ending position of a given target value. 2 | 3 | Your algorithm’s runtime complexity must be in the order of O(log n). 4 | 5 | If the target is not found in the array, return [-1, -1].''' 6 | def searchForARange(arr,target): 7 | n = len(arr) 8 | first_occurence = -1 9 | floor_index = 0 10 | ceiling_index = n-1 11 | while floor_index < ceiling_index: 12 | mid = (floor_index + ceiling_index)/2 13 | if arr[mid] == target: 14 | first_occurence = mid 15 | ceiling_index = mid-1 16 | elif arr[mid] > target: 17 | ceiling_index = mid -1 18 | else: 19 | floor_index = mid + 1 20 | second_occurence = -1 21 | floor_index = first_occurence 22 | ceiling_index = n-1 23 | while floor_index <= ceiling_index: 24 | mid = (floor_index +ceiling_index)/2 25 | if arr[mid] == target: 26 | second_occurence = mid 27 | floor_index = mid + 1 28 | else: 29 | ceiling_index = mid - 1 30 | return first_occurence-1,second_occurence 31 | 32 | arr = [5,7,7,8,8,10] 33 | target = 7 34 | print searchForARange(arr,target) 35 | -------------------------------------------------------------------------------- /Binary-Search/Square-root-of-integer.py: -------------------------------------------------------------------------------- 1 | from math import floor 2 | def sqrtsearch(x): 3 | start = 1 4 | end = x 5 | ans = 0 6 | if x == 0 or x == 1: 7 | return x 8 | while start <= end: 9 | mid = (start+end)/2 10 | if x == mid*mid: 11 | return mid 12 | elif x > (mid*mid): 13 | start = mid + 1 14 | ans = mid 15 | else: 16 | end = mid - 1 17 | return floor(ans) 18 | 19 | x = 11 20 | print sqrtsearch(x) 21 | -------------------------------------------------------------------------------- /Binary-Search/sorted-insert-position.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. 3 | 4 | You may assume no duplicates in the array. 5 | ''' 6 | class Solution: 7 | # @param A : list of integers 8 | # @param B : integer 9 | # @return an integer 10 | def searchInsert(self, arr, target): 11 | 12 | floor_index = 0 13 | ceiling_index = len(arr) - 1 14 | if len(arr) == 1 and arr[0] == target: 15 | return 0 16 | if arr[ceiling_index-1] < target: 17 | return ceiling_index + 1 18 | 19 | while floor_index < ceiling_index: 20 | mid = (floor_index + ceiling_index)/2 21 | if arr[mid] == target: 22 | return mid 23 | elif arr[mid] > target: 24 | ceiling_index = mid-1 25 | ans = mid -1 26 | else: 27 | floor_index = mid + 1 28 | ans = mid + 1 29 | if arr[ans] < target: 30 | return ans + 1 31 | else: 32 | return ans 33 | -------------------------------------------------------------------------------- /Bit-Manipulation/Min-XOR-Value.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given an array of N integers, find the pair of integers in the array which have minimum XOR value. Report the minimum XOR value. 3 | ''' 4 | def minXOR(arr): 5 | arr = sorted(arr) 6 | n = len(arr) 7 | minXor = float('inf') 8 | val = 0 9 | for i in range(n-1): 10 | val = arr[i]^arr[i+1] 11 | minXor = min(minXor,val) 12 | 13 | return minXor 14 | 15 | arr = [0,4,7,9] 16 | print minXOR(arr) 17 | -------------------------------------------------------------------------------- /Bit-Manipulation/Power-of-2.py: -------------------------------------------------------------------------------- 1 | def isPowerofTwo(n): 2 | return n and (not(n and (n-1))) 3 | print isPowerofTwo(9) 4 | -------------------------------------------------------------------------------- /Bit-Manipulation/Xor-upto-n.py: -------------------------------------------------------------------------------- 1 | def xorUptoN(n): 2 | if n%4 == 0: 3 | return n 4 | if n%4 == 1: 5 | return 1 6 | if n%4 == 2: 7 | return n + 1 8 | else: 9 | return 0 10 | 11 | print xorUptoN(6) 12 | -------------------------------------------------------------------------------- /Bit-Manipulation/divide-integers.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return an integer 3 | def divide(self, dividend, divisor): 4 | positive = (dividend < 0) ^ (divisor < 0) 5 | dividend, divisor = abs(dividend), abs(divisor) 6 | res = 0 7 | while dividend >= divisor: 8 | temp, i = divisor, 1 9 | while dividend >= temp: 10 | dividend -= temp 11 | res += i 12 | i <<= 1 13 | temp <<= 1 14 | if not positive: 15 | res = -res 16 | return min(max(-2147483648, res), 2147483647) 17 | -------------------------------------------------------------------------------- /Bit-Manipulation/number-of-1-bits.py: -------------------------------------------------------------------------------- 1 | #Approach 1 2 | def setbits(n): 3 | a = bin(n) 4 | a = a[2:] 5 | return a.count('1') 6 | 7 | n = 4 8 | print setbits(n) 9 | 10 | #Approach 2 11 | def num1bits(n): 12 | res = 0 13 | while n != 0: 14 | if n&1: 15 | res += 1 16 | 17 | #Shifting by one bit to the right 18 | n = n >> 1 19 | return res 20 | -------------------------------------------------------------------------------- /Bit-Manipulation/reverseBit.py: -------------------------------------------------------------------------------- 1 | def reversebit(num): 2 | n = '{0:032b}'.format(num) 3 | rev = n[::-1] 4 | return int(rev,2) 5 | 6 | num = 4294967295 7 | print reversebit(num) 8 | -------------------------------------------------------------------------------- /Bit-Manipulation/single-number.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given an array of integers, every element appears twice except for one. Find that single one. 3 | 4 | Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 5 | 6 | Example : 7 | 8 | Input : [1 2 2 3 1] 9 | Output : 3 10 | ''' 11 | def singlenum(arr): 12 | res = 0 13 | for i in arr: 14 | res ^= i 15 | return res 16 | arr= [1,2,2,3,1] 17 | print singlenum(arr) 18 | -------------------------------------------------------------------------------- /Doublylinkedlist/DLL_deletion.py: -------------------------------------------------------------------------------- 1 | import gc 2 | def delete(dele): 3 | #If node to be deleted is head node 4 | if head==dele: 5 | head=dele.next 6 | #if node to be deleted is not the last node 7 | if dele.next is not None: 8 | dele.next.prev=dele.prev 9 | #if node to be deleted is not the first node 10 | if dele.prev is not None: 11 | dele.prev.next=del.next 12 | #free memory 13 | gc.collect() 14 | -------------------------------------------------------------------------------- /Doublylinkedlist/DLL_insertion.py: -------------------------------------------------------------------------------- 1 | #Insertion at front 2 | def insertafter(head,data): 3 | new_node=node(data) 4 | new_node.next=head 5 | new_node.prev=None 6 | if head is not None: 7 | head.prev=new_node 8 | head=new_node 9 | 10 | #Add a node after a given node 11 | def insertafter(prev_node,data): 12 | if prev_node is None: 13 | return 14 | #Allocate new node 15 | new_node=node(data) 16 | #Make ne xt of new_node as next of prev_node 17 | new_node.next=prev_node.next 18 | #Make next of prev_node as next of new_node 19 | prev_node.next=new_node.next 20 | #Make prev_node as previous of new_node 21 | new_node.prev=prev_node 22 | if (new_node.next is not None): 23 | new_node.next.prev=new_node 24 | #Add a Node at end 25 | def insertend(head,data): 26 | new_node=Node(data) 27 | last=head 28 | #This new node is going to be last node,so make it as NULL 29 | new_node.next=None 30 | if head is not None: 31 | new_node.prev=None 32 | head=new_node 33 | return 34 | while (last.next is not none): 35 | last=last.next 36 | #Change next of last node 37 | last.next=new_node 38 | #Make last node as previous of new node 39 | new_node.prev=last 40 | return 41 | 42 | -------------------------------------------------------------------------------- /Doublylinkedlist/DLL_reverse.py: -------------------------------------------------------------------------------- 1 | def reverse(): 2 | temp=None 3 | curr=head 4 | #swap next and prev for all nodes of doubly linked list 5 | while temp is not None: 6 | temp=curr.prev 7 | curr.prev=curr.next 8 | curr.next=prev 9 | curr=curr.prev 10 | #before changing cases check for cases 11 | if temp is not None: 12 | head=temp.prev 13 | 14 | -------------------------------------------------------------------------------- /Doublylinkedlist/DLLfullsamplecode.py: -------------------------------------------------------------------------------- 1 | 2 | class Node: 3 | #constructor to create a new node 4 | def __init__(self,data): 5 | self.data=data 6 | self.next=None 7 | self.prev=None 8 | class dll: 9 | #constructor for empty doublylinkedlist 10 | def __init__(self): 11 | self.head=None 12 | #function for reverse a doubly linked list 13 | def reverse(): 14 | temp=None 15 | curr=head 16 | #swap next and prev for all nodes of doubly linked list 17 | while temp is not None: 18 | temp=curr.prev 19 | curr.prev=curr.next 20 | curr.next=prev 21 | curr=curr.prev 22 | #before changing cases check for cases 23 | if temp is not None: 24 | head=temp.prev 25 | def push(data): 26 | new_node=Node(data) 27 | new_node.next=head 28 | if head is not None: 29 | head.prev=new_node 30 | head=new_node 31 | def printlist(node): 32 | while(node is not None): 33 | print node.data 34 | node=node.next 35 | #Driver program tot test the above function 36 | dll=DoublylinkedList() 37 | dll.push(2) 38 | dll.push(5) 39 | dll.push(7) 40 | dll.push(11) 41 | dll.push(6) 42 | print "\n Linked lsit" 43 | dll.printList(dll.head) 44 | #reverse doubly linked list 45 | dll.reverse() 46 | print "\n Reversed Linked list" 47 | dll.printList(dll.head) 48 | ss 49 | -------------------------------------------------------------------------------- /Doublylinkedlist/introduction: -------------------------------------------------------------------------------- 1 | 2 | -->Doubly linked list contains extra pointer called previous pointer together with the next pointer and data which are there in a singly linked list. 3 | -->Advantage of doubly linked list over singly linked list 4 | -A DLL can traverse in both forward and reverse direction. 5 | -Delete operation in DLL is more efficient than singly linked list 6 | -->Disadvantage of doubly linked list over singly linked list 7 | -Every node of DLL require extra space for an previous pointer. 8 | -All operations require extra pointer to be maintained. 9 | -------------------------------------------------------------------------------- /Dynamic-Programming/Best-Introduction.txt: -------------------------------------------------------------------------------- 1 | #Dynamic Problem Simple Example 2 | #exxplained in an easy way 3 | A *writes down "1+1+1+1+1+1+1+1 =" on a sheet of paper* 4 | 5 | A : "What's that equal to?" 6 | B : *counting* "Eight!" 7 | 8 | A *writes down another "1+" on the left* 9 | A : "What about that?" 10 | B : *quickly* "Nine!" 11 | A : "How'd you know it was nine so fast?" 12 | A : "You just added one more" 13 | A : "So you didn't need to recount because you remembered there were eight! Dynamic Programming is just a fancy way to say 'remembering stuff to save time later'" 14 | 15 | This convo has the essence of Dynamic Programming 16 | 17 | The idea is very simple, If you have solved a problem with the given input, then save the result for future reference, so as to avoid solving the same problem again.. shortly ‘Remember your Past’. 18 | If the given problem can be broken up in to smaller sub-problems and these smaller subproblems are in turn divided in to still-smaller ones, and in this process, if you observe some overlapping subproblems, then its a big hint for DP. 19 | Also, the optimal solutions to the subproblems contribute to the optimal solution of the given problem. 20 | For Example Consider this simple recursive fibonacci Algorithm 21 | 22 | def fibo(n): 23 | if n<=1: 24 | return n 25 | return fibo(n-1) + fibo(n-2) 26 | 27 | Now let us try to think about complexity of above code.We all know that it will lead 28 | to exponential in terms of n 29 | What we will do is we will try to save the value computed so that we donot have 30 | to recompute it again. 31 | -------------------------------------------------------------------------------- /Dynamic-Programming/CoinChange.py: -------------------------------------------------------------------------------- 1 | def coinChange(coins,total): 2 | m = [[0 for i in range(total+1)] for i in range(len(coins)+1)] 3 | 4 | for i in range(r+1): 5 | m[0][i] = i 6 | 7 | for row in range(1,len(coins)+1): 8 | for col in range(1,n+1): 9 | if coins[row-1] == col: 10 | m[row][col] = 1 11 | #Coins[c-1] can't be included 12 | elif coins[row-1] > col: 13 | m[row][col] = m[row-1][col] 14 | #coin[c-1] cn be used 15 | else: 16 | m[row][col] = min(m[row-1][col],1+m[row][col-coins[row-1]]) 17 | return m[-1][-1] 18 | -------------------------------------------------------------------------------- /Dynamic-Programming/DP-memoization-Technique.py: -------------------------------------------------------------------------------- 1 | #There are two ways to store the values so that these values can be reused 2 | #Method -1) Memoization 3 | # ->It is similar to recursive version with a small modification that 4 | # it looks into the lookup table before computing solution 5 | 6 | #Fibonnaci Example memoized version 7 | def fib(n, lookup): 8 | #Base Case 9 | if n == 0 or n == 1: 10 | lookup[n] = n 11 | 12 | #if the value is not calculated previously then calculate it 13 | if lookup[n] is None: 14 | lookup[n] = fib(n-1,lookup) + fib(n-2.lookup) 15 | 16 | #Return the value corresponding to that value of n 17 | return lookup[n] 18 | 19 | n = 34 20 | lookup = [None]*101 21 | 22 | print fib(n,lookup) 23 | -------------------------------------------------------------------------------- /Dynamic-Programming/DP-tabulation-technique.py: -------------------------------------------------------------------------------- 1 | #The tabulation technique builds a table in bottom up fashion and returns the last entry 2 | #from the table 3 | #For example, for the same fibonacci algo,we first calculate fib(0) then fib(1) and so on 4 | 5 | #Illustrated below 6 | def fib(n): 7 | #array declaration 8 | f = [0]*(n+1) 9 | #base case assignment 10 | f[1] = 1 11 | 12 | for i in range(2,n+1): 13 | f[i] = f[i-1] + f[i-2] 14 | return f[n] 15 | 16 | n = 9 17 | print fib(n) 18 | 19 | #Advantages: 20 | #IT Stores the solution of subproblems. 21 | #Table is filled on demand 22 | #All entries are not necessarily filleds 23 | -------------------------------------------------------------------------------- /Dynamic-Programming/Fibonacci-number.py: -------------------------------------------------------------------------------- 1 | #Taking fib of first two number 2 | #Time complexity: O(n) 3 | #Extra Space: O(n) 4 | fibarray = [0, 1] 5 | def fibonacci(n): 6 | if n < 0: 7 | raise IndexError("Please input a non-negative number") 8 | elif n <= len(fibarray): 9 | return fibarray[n-1] 10 | else: 11 | temp = fibonacci(n-1) + fibonacci(n-2) 12 | fibarray.append(temp) 13 | return temp 14 | 15 | print fibonacci(3) 16 | -------------------------------------------------------------------------------- /Dynamic-Programming/LengthOfLongestBitonicSubsequence.py: -------------------------------------------------------------------------------- 1 | def lbs(arr): 2 | n = len(arr) 3 | lis = [1 for i in range(n+1)] 4 | 5 | for i in range(1,n): 6 | for j in range(0, i): 7 | if (arr[i] > arr[j]) and lis[i] < lis[j] + 1: 8 | lis[i] = lis[j]+1 9 | lds = [1 for i in range(n+1)] 10 | 11 | for i in reversed(range(n-1)):#loop from n-2 to 0 12 | for j in reversed(range(i-1,n)):#loop from n-1 downto i-1 13 | if arr[i] > arr[j] and lds[i] < lds[j]+1: 14 | lds[i] = lds[j]+1 15 | 16 | maximum = lis[0] + lds[0] - 1 17 | for i in range(1, n): 18 | maximum = max((lis[i]+lds[i]-1),maximum) 19 | return maximum 20 | 21 | arr = [ 64, 263, 11, 188, 396, 268, 116, 453, 207, 39, 312, 401, 396, 476, 56, 277, 104, 213, 79, 128, 36, 393, 117, 298, 371, 73, 110, -3, 350, 144, 210, 491, 312, 351, 183, 25, 230, 303, 478, 476, 276, 127, 184, 390, 481, 63, 270, 417, 257, 189, 18, 53, 80, 122, 358, 469, 244, 144, 152, 83, 188, 174, 381, 499, 280, 67, -1, 95, 489, 428, 302, 327, 25, 419, 207, 499, 457, 239, 12, 438, 54, 473, 116, 355, 428, -8, 37, 292, 116, 361, 186, 396, 375, -8, 416, 21, -8, 231, 51, 271, 318, 214, 361, 196, 118, 434, 133, 366, 192, 244, 400, 88, 444, 251, 165, 286, 15, 0, 223, 74, 84, 456, 464, 50, 209, 137, 67, 74, 4, 397, 403, 156, 70, 39, 187, 483, 267, 187, 464, 361, 74, 398, 479, 107, 123, 358, 317, 209, 192, 157, 61, 437, 330, -2, 276, 418, 418, 286, 303, 335, 317, 394, 193, 252, 64, 71, 322, 397, 494, 480, 285, 25, 298, 227, 16, 382, 452, 75, 304, 172, 469, 334, 294, 181, 394, 163, 326, 169, 30, 39, 425, 105, 294, 354, 207, 314, 386, 494 ] 22 | print "Length of LBS is",lbs(arr) 23 | 24 | #Another Approach 25 | class Solution: 26 | # @param A : tuple of integers 27 | # @return an integer 28 | def longestSubsequenceLength(self, A): 29 | m=0 30 | L=[1]*len(A) 31 | for i in range(1,len(A)): 32 | for j in range(i): 33 | if A[j]m: 43 | m=val 44 | return m 45 | -------------------------------------------------------------------------------- /Dynamic-Programming/Longest-increasing-subsequence.py: -------------------------------------------------------------------------------- 1 | """find the length of the longest subsequence of a given sequence 2 | such that all elements of the subsequence are sorted in increasing order. 3 | For example, the length of LIS for {10, 22, 9, 33, 21, 50, 41, 60, 80} is 6 4 | and LIS is {10, 22, 33, 50, 60, 80}""" 5 | #Dynamic Programming Approach 6 | #Complexity O(n^2) 7 | #There is better way to do this in O(nlogn) but to show u a simple example of DP 8 | #We have used thi LCS example 9 | def lis(arr): 10 | n = len(arr) 11 | 12 | lis = [1]*n 13 | for i in range(1,n): 14 | for j in range(0,i): 15 | if arr[i] > arr[j] and lis[i] < lis[j]+1: 16 | lis[i] = lis[j] + 1 17 | 18 | maximum = 0 19 | return max(lis) 20 | 21 | arr = [10,22,9,33,21,50,41,60] 22 | print lis(arr) 23 | -------------------------------------------------------------------------------- /Dynamic-Programming/LongestCommonSubsequence.py: -------------------------------------------------------------------------------- 1 | #Recursive Approach 2 | def lcs(s1, s2): 3 | m = len(s1) 4 | n = len(s2) 5 | if m == 0 or n ==0 : 6 | return 0 7 | elif s1[m-1] == s2[n-2]: 8 | return 1 + lcs(s1[:m-1], s2[:n-1]) 9 | else: 10 | return max(lcs(s1,s2[:n-1]), lcs(s1[:m-1],s2)) 11 | 12 | x = "AGGTAB" 13 | y = "GXTXAYB" 14 | print "Length of lcs is " , lcs(x, y) 15 | 16 | #Dynamic Approach 17 | def lcs(x, y): 18 | m = len(x) 19 | n = len(y) 20 | table = [[0]*(n+1) for i in range(m+1)] 21 | for i in range(m+1): 22 | for j in range(n+1): 23 | if i == 0 or j == 0: 24 | table[i][j] = 0 25 | elif x[i-1] == y[j-1]: 26 | table[i][j] = 1 + table[i-1][j-1] 27 | else: 28 | table[i][j] = max(table[i-1][j],table[i][j-1]) 29 | return table[m][n] 30 | x = "AGGTAB" 31 | y = "GXTXAYB" 32 | print "Length is ", lcs(x,y) 33 | -------------------------------------------------------------------------------- /Dynamic-Programming/LongestPalindromeSubsequence.py: -------------------------------------------------------------------------------- 1 | def longestPalindromeSubsequence(s): 2 | n = len(s) 3 | dp = [[0 for i in range(n)] for i in range(n)] 4 | #length 1 are all palindromes 5 | for i in range(n): 6 | dp[i][i] = 1 7 | 8 | #Length > 1 9 | for l in range(2,n+1): 10 | for i in range(n-l+1): 11 | j = i+l-1 12 | if l == 2 and s[i] == s[j]: 13 | dp[i][j] = 2 14 | elif s[i] == s[j]: 15 | dp[i][j] = dp[i+1][j-1] + 2 16 | else: 17 | dp[i][j] = max(dp[i+1][j],dp[i][j-1]) 18 | return dp[0][n-1] 19 | print longestPalindromeSubsequence("agbdba") 20 | -------------------------------------------------------------------------------- /Dynamic-Programming/Word-break.py: -------------------------------------------------------------------------------- 1 | def wordBreak(s,dic): 2 | segmented = [True] 3 | for i in range(len(s)): 4 | segmented.append(False) 5 | for j in range(i,-1,-1): 6 | if segmented[j] and s[j:i+1] in dic: 7 | segmented[i+1] = True 8 | break 9 | return segmented[len(s)] 10 | s = "myinterviewtrainer" 11 | dic = ["interview","my","trainer"] 12 | print wordBreak(s,dic) 13 | -------------------------------------------------------------------------------- /Dynamic-Programming/interleavingString.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. 3 | 4 | Example, 5 | Given: 6 | 7 | s1 = "aabcc", 8 | s2 = "dbbca", 9 | When s3 = "aadbbcbcac", return true. 10 | When s3 = "aadbbbaccc", return false. 11 | 12 | Return 0 / 1 ( 0 for false, 1 for true ) for this problem 13 | ''' 14 | class Solution: 15 | # @param A : string 16 | # @param B : string 17 | # @param C : string 18 | # @return an integer 19 | def isInterleave(self, a, b, c): 20 | m = len(a) 21 | n = len(b) 22 | 23 | table = [[False for i in range(n+1)] for i in range(m+1)] 24 | 25 | if m+n != len(c): 26 | return False 27 | 28 | for i in range(m+1): 29 | for j in range(n+1): 30 | if i == 0 and j == 0: 31 | table[i][j] = True 32 | elif i == 0 and (b[j-1] == c[j-1]): 33 | table[i][j] = table[i][j-1] 34 | elif j == 0 and a[i-1] == c[i-1]: 35 | table[i][j] = table[i-1][j] 36 | elif a[i-1] == c[i+j-1] and b[j-1] != c[i+j-1]: 37 | table[i][j] = table[i-1][j] 38 | elif a[i-1] != c[i+j-1] and b[j-1] == c[i+j-1]: 39 | table[i][j] = table[i][j-1] 40 | elif a[i-1] == c[i+j-1] and b[j-1] == c[i+j-1]: 41 | table[i][j] = table[i-1][j] or table[i][j-1] 42 | return table[m][n] 43 | -------------------------------------------------------------------------------- /Dynamic-Programming/longestIncreasingSubsequence.py: -------------------------------------------------------------------------------- 1 | #Complexity O(n*n) 2 | def lis(arr): 3 | n = len(arr) 4 | 5 | dp = [1]*n 6 | 7 | for i in range(1, n): 8 | for j in range(0,i): 9 | if arr[i] > arr[j] and dp[i] < dp[j] + 1: 10 | dp[i] = dp[j] + 1 11 | return max(dp) 12 | arr = [10,22,9,33,21,50,41,60] 13 | print "Length of LIS is ", lis(arr) 14 | -------------------------------------------------------------------------------- /Dynamic-Programming/longestValidParentheses.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. 3 | 4 | For "(()", the longest valid parentheses substring is "()", which has length = 2. 5 | 6 | Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4. 7 | ''' 8 | class Solution: 9 | # @param A : string 10 | # @return an integer 11 | def longestValidParentheses(self, string): 12 | n = len(string) 13 | stack = [-1] 14 | res = 0 15 | for i in range(n): 16 | if string[i] == '(': 17 | stack.append(i) 18 | else: 19 | stack.pop() 20 | if len(stack) != 0: 21 | res = max(res, i- stack[len(stack)-1]) 22 | else: 23 | stack.append(i) 24 | return res 25 | -------------------------------------------------------------------------------- /Graph/DirectedBFS.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | class Graph: 4 | def __init__(self): 5 | #default dictionary to store Graph 6 | self.graph = defaultdict(list) 7 | #Function to add an edge to graph 8 | def addEdge(self,u,v): 9 | self.graph[u].append(v) 10 | 11 | def BFS(self,s): 12 | #Mark all the vertices as not visited 13 | visited = [False]*(len(self.graph)) 14 | 15 | #create a queue for BFS 16 | queue = [] 17 | 18 | #Mark the source node as visited adn enqueue it 19 | queue.append(s) 20 | visited[s] = True 21 | 22 | while queue: 23 | #Dequeue a vertex from queue and print it 24 | s=queue.pop(0) 25 | print s, 26 | #GEt all the adjacent vertices of the dequeued vetex s 27 | #if a adjacent has not been visited yet ,then mark it visited 28 | #and enqueue it 29 | for i in self.graph[s]: 30 | if visited[i] ==False: 31 | queue.append(i) 32 | visited[i] = True 33 | 34 | g = Graph() 35 | g.addEdge(0,1) 36 | g.addEdge(0,2) 37 | g.addEdge(1,2) 38 | g.addEdge(2,0) 39 | g.addEdge(2,3) 40 | g.addEdge(3,3) 41 | print "BFS Traversal" 42 | g.BFS(2) 43 | -------------------------------------------------------------------------------- /Graph/UndirectedDFS.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | # This class represents a directed graph using 4 | # adjacency list representation 5 | class Graph: 6 | 7 | # Constructor 8 | def __init__(self): 9 | 10 | # default dictionary to store graph 11 | self.graph = defaultdict(list) 12 | 13 | # function to add an edge to graph 14 | def addEdge(self,u,v): 15 | self.graph[u].append(v) 16 | 17 | # A function used by DFS 18 | def DFSUtil(self,v,visited): 19 | 20 | # Mark the current node as visited and print it 21 | visited[v]= True 22 | print v, 23 | 24 | # Recur for all the vertices adjacent to this vertex 25 | for i in self.graph[v]: 26 | if visited[i] == False: 27 | self.DFSUtil(i, visited) 28 | 29 | 30 | # The function to do DFS traversal. It uses 31 | # recursive DFSUtil() 32 | def DFS(self,v): 33 | 34 | # Mark all the vertices as not visited 35 | visited = [False]*(len(self.graph)) 36 | 37 | # Call the recursive helper function to print 38 | # DFS traversal starting from all vertices one by one 39 | for i in range(len(self.graph)): 40 | if visited[i] == False: 41 | self.DFSUtil(i,visited) 42 | 43 | 44 | # Driver code 45 | # Create a graph given in the above diagram 46 | g = Graph() 47 | g.addEdge(0, 1) 48 | g.addEdge(0, 2) 49 | g.addEdge(1, 2) 50 | g.addEdge(2, 0) 51 | g.addEdge(2, 3) 52 | g.addEdge(3, 3) 53 | 54 | print "Following is DFS from (starting from vertex 2)" 55 | g.DFS(2) 56 | -------------------------------------------------------------------------------- /Graph/number-of-islands.py: -------------------------------------------------------------------------------- 1 | '''Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.''' 2 | def numIslands(self,grid): 3 | if not grid: 4 | return 0 5 | count = 0 6 | for i in range(len(grid)): 7 | for j in range(len(grid[0])): 8 | if grid[i][j] == '1': 9 | self.dfs(grid,i,j) 10 | count += 1 11 | return count 12 | def dfs(self,grid,i,j): 13 | if i < 0 or j<0 or i >= len(grid) or j >= len(grid[0]) or grid[i][j] != '1': 14 | return 15 | grid[i][j] = '#' 16 | self.dfs(grid,i+1,j) 17 | self.dfs(grid,i-1,j) 18 | self.dfs(grid,i,j+1) 19 | self.dfs(grid,i,j-1) 20 | -------------------------------------------------------------------------------- /Greedy/InterleavingStrings.py: -------------------------------------------------------------------------------- 1 | #Complexity O(M+N) 2 | def isInterleaved(a,b,c): 3 | i, j, k = 0, 0, 0 4 | 5 | while k !=len(c)-1: 6 | if a[i] == c[k]: 7 | i += 1 8 | elif b[j] == c[k]: 9 | j += 1 10 | else: 11 | return 0 12 | 13 | k += 1 14 | if a[i-1] or b[j-1]: 15 | return 0 16 | return 1 17 | 18 | a = "AB" 19 | b = "CD" 20 | c = "ACBG" 21 | if isInterleaved(a,b,c) == 1: 22 | print c + "is Interleaved of "+ a + " and " + b 23 | else: 24 | print "Not Interleaved" 25 | 26 | 27 | #Dynamic Approach 28 | def isInterleaved(a,b,c): 29 | m = len(a) 30 | n = len(b) 31 | 32 | table = [[False for i in range(n+1)] for i in range(m+1)] 33 | 34 | if m+n != len(c): 35 | return False 36 | 37 | for i in range(m+1): 38 | for j in range(n+1): 39 | if i == 0 and j == 0: 40 | table[i][j] = True 41 | elif i == 0 and (b[j-1] == c[j-1]): 42 | table[i][j] = table[i][j-1] 43 | elif j == 0 and a[i-1] == c[i-1]: 44 | table[i][j] = table[i-1][j] 45 | elif a[i-1] == c[i+j-1] and b[j-1] != c[i+j-1]: 46 | table[i][j] = table[i-1][j] 47 | elif a[i-1] != c[i+j-1] and b[j-1] == c[i+j-1]: 48 | table[i][j] = table[i][j-1] 49 | elif a[i-1] == c[i+j-1] and b[j-1] == c[i+j-1]: 50 | table[i][j] = table[i-1][j] or table[i][j-1] 51 | return table[m][n] 52 | -------------------------------------------------------------------------------- /Greedy/bulbs.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | N light bulbs are connected by a wire. Each bulb has a switch associated with it, however due to faulty wiring, a switch also changes the state of all the bulbs to the right of current bulb. Given an initial state of all bulbs, find the minimum number of switches you have to press to turn on all the bulbs. You can press the same switch multiple times. 4 | 5 | Note : 0 represents the bulb is off and 1 represents the bulb is on. 6 | 7 | Example: 8 | 9 | Input : [0 1 0 1] 10 | Return : 4 11 | 12 | Explanation : 13 | press switch 0 : [1 0 1 0] 14 | press switch 1 : [1 1 0 1] 15 | press switch 2 : [1 1 1 0] 16 | press switch 3 : [1 1 1 1] 17 | ''' 18 | class Solution: 19 | # @param A : list of integers 20 | # @return an integer 21 | def bulbs(self, A): 22 | c=0 23 | n=len(A) 24 | i=0 25 | state=0 26 | for i in xrange(len(A)): 27 | if A[i]==state: 28 | c+=1 29 | state=1-state 30 | return c 31 | 32 | -------------------------------------------------------------------------------- /Greedy/gas-Station.py: -------------------------------------------------------------------------------- 1 | ''' 2 | There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. 3 | 4 | You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. 5 | 6 | Return the minimum starting gas station’s index if you can travel around the circuit once, otherwise return -1. 7 | 8 | You can only travel in one direction. i to i+1, i+2, ... n-1, 0, 1, 2.. 9 | Completing the circuit means starting at i and ending up at i again. 10 | ''' 11 | def canCompleteCircuit(gas,cost): 12 | if len(gas) == 0 or len(cost) == 0 or sum(gas) < sum(cost): 13 | return -1 14 | pos = 0 15 | fuel = 0 16 | for i in range(len(gas)): 17 | fuel += gas[i] - cost[i] 18 | if fuel < 0: 19 | fuel = 0 20 | pos = i+1 21 | return pos 22 | -------------------------------------------------------------------------------- /Greedy/highestProduct.py: -------------------------------------------------------------------------------- 1 | arr = map(int,raw_input().split()) 2 | max_ = float('inf') 3 | n = len(arr) 4 | arr = sorted(arr, reverse = True) 5 | max_ = arr[0]*arr[1]*arr[2] 6 | to_check = arr[n-1]*arr[n-2] 7 | if max_ > arr[0]*to_check: 8 | print max_ 9 | else: 10 | print arr[0]*to_check 11 | -------------------------------------------------------------------------------- /Greedy/majorityElement.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given an array of size n, find the majority element. The majority element is the element that appears more than floor(n/2) times. 3 | 4 | You may assume that the array is non-empty and the majority element always exist in the array. 5 | 6 | Example : 7 | 8 | Input : [2, 1, 2] 9 | Return : 2 which occurs 2 times which is greater than 3/2. 10 | ''' 11 | import math 12 | def majority(arr): 13 | n = len(arr) 14 | res = 0 15 | for i in arr: 16 | if arr.count(i) > math.floor(n/2): 17 | res = i 18 | break 19 | return res 20 | 21 | print majority([2,1,2]) 22 | -------------------------------------------------------------------------------- /Greedy/seats.py: -------------------------------------------------------------------------------- 1 | arr = map(str,raw_input().split()) 2 | n = len(arr) 3 | index_lis = [i for i in range(n) if arr[i] == 'x'] 4 | index_len = len(index_lis) 5 | if index_len <=1 : 6 | print 0 7 | median = 0 8 | if index_len%2 == 1: 9 | median = index_lis[index_len/2] 10 | else: 11 | median = (index_lis[index_len/2] + index_lis[index_len/2 - 1] + 1)/2 12 | step = 0 13 | target = median 14 | for i in range((index_len-2)/2,-1,-1): 15 | step += target-index_lis[i] 16 | target -= 1 17 | target = median 18 | for i in range(index_len/2,index_len): 19 | step += index_lis[i] - target 20 | target += 1 21 | print step%10000003 22 | -------------------------------------------------------------------------------- /Hashing/4-sum.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. 3 | ''' 4 | class Solution: 5 | # @param A : list of integers 6 | # @param B : integer 7 | # @return a list of list of integers 8 | def fourSum(self, arr, target): 9 | i = 0 10 | j = 1 11 | flag = 0 12 | n = len(arr) 13 | ans = [] 14 | if n < 4: 15 | return ans 16 | arr.sort() 17 | while i < n-3: 18 | j = i+1 19 | while j < n-2: 20 | num = target - (arr[i]+arr[j]) 21 | k = j+1 22 | l = n-1 23 | while k < l: 24 | sum_ = arr[k]+arr[l] 25 | if sum_ == num: 26 | ans.append([arr[i],arr[j],arr[k],arr[l]]) 27 | while arr[k] == arr[k+1] and k < n-2: 28 | k += 1 29 | while arr[l] == arr[l-1] and l > 0: 30 | l -= 1 31 | k += 1 32 | l -= 1 33 | elif sum_ < num: 34 | k += 1 35 | else: 36 | l -= 1 37 | while arr[j] == arr[j+1] and j < n-2: 38 | j += 1 39 | j += 1 40 | while arr[i] == arr[i+1] and i < n-2: 41 | i += 1 42 | i += 1 43 | return ans 44 | -------------------------------------------------------------------------------- /Hashing/longest-substring-without-repeat.py: -------------------------------------------------------------------------------- 1 | def lengthOfLongestSubstring(arr): 2 | max_length = 0 3 | i = 0 4 | j = i+1 5 | n = len(arr) 6 | ans = arr[0] 7 | while j < n: 8 | if arr[j] not in arr[i:j]: 9 | len_ = len(arr[i:j+1]) 10 | if len_ > max_length: 11 | max_length = len_ 12 | ans = arr[i:j+1] 13 | j += 1 14 | else: 15 | i += 1 16 | j = i+1 17 | return ans 18 | 19 | 20 | s = raw_input() 21 | print lengthOfLongestSubstring(s) 22 | 23 | 24 | #Approach 2 25 | class Solution: 26 | # @param A : string 27 | # @return an integer 28 | def lengthOfLongestSubstring(self, A): 29 | prev = {c:-1 for c in A} 30 | best, prev_best = 1, 1 31 | for i in range(1, len(A)): 32 | prev[A[i-1]] = i-1 33 | prev_best = min(i-prev[A[i]], prev_best+1) 34 | best = max(best, prev_best) 35 | return best 36 | -------------------------------------------------------------------------------- /LINKEDLIST/AddTwoLinkedList.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.data = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def push(self,new_data): 11 | new_node = Node(new_data) 12 | new_node.next = self.head 13 | self.head = new_node 14 | 15 | def addTwoLists(self,first,second): 16 | prev = temp = None 17 | carry = 0 18 | while (first is not None or second is not None): 19 | fdata = 0 if first is None else first.data 20 | sdata = 0 if second is None else second.data 21 | 22 | sum = carry +fdata +sdata 23 | 24 | carry = 0 if sum<10 else 1 25 | 26 | sum= sum if sum<10 else sum%10 27 | 28 | temp = Node(sum) 29 | 30 | if self.head is None: 31 | self.head = temp 32 | else: 33 | prev.next =temp 34 | 35 | prev = temp 36 | 37 | if first is not None: 38 | first = first.next 39 | 40 | if second is not None: 41 | second = second.next 42 | 43 | if carry >0: 44 | temp.next = Node(carry) 45 | 46 | def printList(self): 47 | curr = self.head 48 | while curr: 49 | print curr.data 50 | curr= curr.next 51 | 52 | 53 | 54 | firstLinkedList = LinkedList() 55 | secondLinkedList = LinkedList() 56 | firstLinkedList.push(5) 57 | firstLinkedList.push(6) 58 | firstLinkedList.push(3) 59 | firstLinkedList.push(5) 60 | firstLinkedList.push(7) 61 | 62 | print "first LinkedList is" 63 | firstLinkedList.printList() 64 | 65 | secondLinkedList.push(4) 66 | secondLinkedList.push(5) 67 | 68 | print "second list is " 69 | print secondLinkedList.printList() 70 | 71 | res = LinkedList() 72 | res.addTwoLists(firstLinkedList.head,secondLinkedList.head) 73 | print "Resultant list is " 74 | res.printList() 75 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_DELETION.py: -------------------------------------------------------------------------------- 1 | # Python program to delete a node from linked list 2 | 3 | # Node class 4 | class Node: 5 | 6 | # Constructor to initialize the node object 7 | def __init__(self, data): 8 | self.data = data 9 | self.next = None 10 | 11 | class LinkedList: 12 | 13 | # Function to initialize head 14 | def __init__(self): 15 | self.head = None 16 | 17 | # Function to insert a new node at the beginning 18 | def push(self, new_data): 19 | new_node = Node(new_data) 20 | new_node.next = self.head 21 | self.head = new_node 22 | 23 | # Given a reference to the head of a list and a key, 24 | # delete the first occurence of key in linked list 25 | def deleteNode(self, key): 26 | 27 | # Store head node 28 | temp = self.head 29 | 30 | # If head node itself holds the key to be deleted 31 | if (temp is not None): 32 | if (temp.data == key): 33 | self.head = temp.next 34 | temp = None 35 | return 36 | 37 | # Search for the key to be deleted, keep track of the 38 | # previous node as we need to change 'prev.next' 39 | while(temp is not None): 40 | if temp.data == key: 41 | break 42 | prev = temp 43 | temp = temp.next 44 | 45 | # if key was not present in linked list 46 | if(temp == None): 47 | return 48 | 49 | # Unlink the node from linked list 50 | prev.next = temp.next 51 | 52 | temp = None 53 | 54 | 55 | # Utility function to print the linked LinkedList 56 | def printList(self): 57 | temp = self.head 58 | while(temp): 59 | print " %d" %(temp.data), 60 | temp = temp.next 61 | 62 | 63 | # Driver program 64 | llist = LinkedList() 65 | llist.push(7) 66 | llist.push(1) 67 | llist.push(3) 68 | llist.push(2) 69 | 70 | print "Created Linked List: " 71 | llist.printList() 72 | llist.deleteNode(1) 73 | print "\nLinked List after Deletion of 1:" 74 | llist.printList() 75 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_INSERTION.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.data = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | """Inserting node at front """ 10 | def push_front(self,new_data): 11 | new_node = Node(new_data) #creating new Node 12 | new_node.next = self.head 13 | self.head =new_node 14 | """Inserting node after a given node""" 15 | def push_after(self,prev_node,new_data): 16 | if prev_node is None: 17 | print "no previous node" 18 | return 19 | new_node = Node(new_data) 20 | new_node.next = prev_node.next 21 | prev_node.next = new_node 22 | """Inserting node at the end of LinkedList""" 23 | def push_end(self,new_data): 24 | new_node = Node(new_data) 25 | last = self.head 26 | while(last.next): 27 | last=last.next 28 | last.next = new_node 29 | def printlist(self): 30 | temp = self.head 31 | while(temp): 32 | print temp.data 33 | temp =temp.next 34 | if __name__ =='__main__': 35 | ll=LinkedList() 36 | ll.push_front(1) 37 | ll.push_after(ll.head.next,8) 38 | ll.push_end(9) 39 | print "Created LinkedList list is :" 40 | ll.printlist() 41 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_INTRO.py: -------------------------------------------------------------------------------- 1 | 2 | #uses python2 3 | Class Node: 4 | def __init__(self,data): 5 | self.data=data #intializes data 6 | self.next=None 7 | Class Linkedlist: 8 | def __init__(self): 9 | self.head=None #initializes head 10 | #Main Part 11 | if __name__ =='__main__': 12 | ll=Linkedlist() 13 | ll.head=Node(1) 14 | ll.second=Node(2) 15 | ll.third=Node(3) 16 | ll.head.next=second 17 | ll.second.next=third 18 | 19 | 20 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_LENGTH.py: -------------------------------------------------------------------------------- 1 | #Iterative solution for finding length of a LinkedList 2 | class Node: 3 | def __init__(self,data): 4 | self.data = data 5 | self.next = None 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | def push(self,new_data): 10 | new_node = Node(new_data) 11 | new_node.next = self.head 12 | self.head = new_node 13 | def getCount(self): 14 | count = 0; 15 | curr = self.head 16 | while(curr): 17 | curr = curr.next 18 | count +=1 19 | return count 20 | 21 | if __name__ =='__main__': 22 | ll =LinkedList(); 23 | ll.push(1) 24 | ll.push(2) 25 | ll.push(3) 26 | 27 | print 'count of nodes is : ', ll.getCount() 28 | 29 | #Recursive solution for finding length of a LinkedList 30 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_MERGE.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Merge two sorted linked lists and return it as a new list. 5 | # The new list should be made by splicing together the nodes of the first two lists. 6 | # 7 | 8 | # Definition for singly-linked list. 9 | class ListNode(object): 10 | def __init__(self, x): 11 | self.val = x 12 | self.next = None 13 | 14 | def __repr__(self): 15 | if self: 16 | return "{} -> {}".format(self.val, self.next) 17 | 18 | 19 | class Solution(object): 20 | def mergeTwoLists(self, l1, l2): 21 | """ 22 | :type l1: ListNode 23 | :type l2: ListNode 24 | :rtype: ListNode 25 | """ 26 | curr = dummy = ListNode(0) 27 | while l1 and l2: 28 | if l1.val < l2.val: 29 | curr.next = l1 30 | l1 = l1.next 31 | else: 32 | curr.next = l2 33 | l2 = l2.next 34 | curr = curr.next 35 | curr.next = l1 or l2 36 | return dummy.next 37 | 38 | 39 | if __name__ == "__main__": 40 | l1 = ListNode(0) 41 | l1.next = ListNode(1) 42 | l2 = ListNode (2) 43 | l2.next = ListNode(3) 44 | print Solution().mergeTwoLists(l1, l2) 45 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_MERGEPOINT: -------------------------------------------------------------------------------- 1 | def FindMergeNode(headA, headB): 2 | currentA=headA 3 | currentB=headB 4 | while(currentA!=currentB): 5 | if(currentA.next is None): 6 | currentA=headB 7 | else: 8 | currentA=currentA.next 9 | 10 | if(currentB.next is None): 11 | currentB=headA 12 | else: 13 | currentB=currentB.next 14 | return currentB.data 15 | 16 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_REVERSE.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.data = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | def rev(self): 10 | prev = None 11 | curr = self.head 12 | while(curr): 13 | next = curr.next 14 | curr.next = prev 15 | prev= curr 16 | curr = next 17 | self.head = prev 18 | def push(self,new_data): 19 | new_node = Node(new_data) 20 | new_node.next = self.head 21 | self.head = new_node 22 | def printList(self): 23 | temp = self.head 24 | while(temp): 25 | print temp.data 26 | temp = temp.next 27 | ll = LinkedList() 28 | ll.push(1) 29 | ll.push(2) 30 | ll.push(3) 31 | ll.push(4) 32 | ll.push(5) 33 | ll.push(6) 34 | print "Original List : " 35 | ll.printList() 36 | 37 | print "Reversed List : " 38 | ll.rev() 39 | ll.printList() 40 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_TRAVERSAL.py: -------------------------------------------------------------------------------- 1 | #uses python2 2 | def traversa(self): 3 | temp=self.head 4 | while(temp): 5 | print temp.data 6 | temp=temp.next 7 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_compare.py: -------------------------------------------------------------------------------- 1 | def CompareLists(headA, headB): 2 | if(headA == None and headB ==None): 3 | return 1 4 | elif(headA ==None or headB ==None): 5 | return 0 6 | 7 | if(headA.data == headB.data): 8 | return CompareLists(headA.next, headB.next) 9 | else: 10 | return 0 11 | 12 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_cycledetection.py: -------------------------------------------------------------------------------- 1 | def has_cycle(head): 2 | slow=head 3 | fast=head 4 | while(slow and fast and fast.next is not None): 5 | slow=slow.next 6 | fast=fast.next.next 7 | if (slow==fast): 8 | return True 9 | else: 10 | return False 11 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_detectloops: -------------------------------------------------------------------------------- 1 | #Rather than checking each node one by one ,we will use a better algo known as Floyd's cycle detection method 2 | # Python program to detect and remove loop in linked list 3 | 4 | class LinkedList: 5 | 6 | # Function to initialize head 7 | def __init__(self): 8 | self.head = None 9 | 10 | def detectAndRemoveLoop(self): 11 | slow_p = fast_p = self.head 12 | 13 | while(slow_p and fast_p and fast_p.next): 14 | slow_p = slow_p.next 15 | fast_p = fast_p.next.next 16 | 17 | # If slow_p and fast_p meet at some point then 18 | # there is a loop 19 | if slow_p == fast_p: 20 | self.removeLoop(slow_p) 21 | 22 | # Return 1 to indicate that loop is found 23 | return 1 24 | 25 | # Return 0 to indicate that there is no loop 26 | return 0 27 | 28 | # Function to remove loop 29 | # loop_node --> pointer to one of the loop nodes 30 | # head --> Pointer to the start node of the linked list 31 | def removeLoop(self, loop_node): 32 | ptr1 = loop_node 33 | ptr2 = loop_node 34 | 35 | # Count the number of nodes in loop 36 | k = 1 37 | while(ptr1.next != ptr2): 38 | ptr1 = ptr1.next 39 | k += 1 40 | 41 | # Fix one pointer to head 42 | ptr1 = self.head 43 | 44 | # And the other pointer to k nodes after head 45 | ptr2 = self.head 46 | for i in range(k): 47 | ptr2 = ptr2.next 48 | 49 | # Move both pointers at the same place 50 | # they will meet at loop starting node 51 | while(ptr2 != ptr1): 52 | ptr1 = ptr1.next 53 | ptr2 = ptr2.next 54 | 55 | # Get pointer to the last node 56 | ptr2 = ptr2.next 57 | while(ptr2.next != ptr1): 58 | ptr2 = ptr2.next 59 | 60 | # Set the next node of the loop ending node 61 | # to fix the loop 62 | ptr2.next = None 63 | 64 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_nodevalue.py: -------------------------------------------------------------------------------- 1 | def GetNode(head, position): 2 | index=0 3 | temp=head 4 | res=head 5 | while(temp is not None): 6 | temp=temp.next 7 | 8 | if (index > position): 9 | 10 | res=res.next 11 | index=index+1 12 | return res.data 13 | -------------------------------------------------------------------------------- /LINKEDLIST/LL_rotate.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.data = data 4 | self.next = None 5 | 6 | 7 | class LinkedList: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def append(self,new_data): 12 | new_node = Node(new_data) 13 | new_node.next = self.head 14 | self.head =new_node 15 | 16 | def rotate(self,k): 17 | curr = self.head 18 | count = 1 19 | 20 | while (count10 else 0 25 | #Update sum if it is greater than 10 26 | sum = sum if sum<10 else sum%10 27 | #create a new node with sum as data 28 | temp = Node(sum) 29 | #if this is the first node then set it as head of resultant list 30 | if self.head is None: 31 | self.head = temp 32 | else: 33 | prev.next = temp 34 | #set prev for next insertion 35 | prev = temp 36 | #Move first and second to next node 37 | if first is not None: 38 | first = first.next 39 | 40 | if second is not None: 41 | second = second.next 42 | 43 | if carry>0: 44 | temp.next = Node(carry) 45 | 46 | def printList(self): 47 | curr= head 48 | while curr: 49 | print curr.data 50 | curr = curr.next 51 | 52 | firstLinkedList = LinkedList() 53 | secondLinkedList = LinkedList() 54 | firstLinkedList.push(5) 55 | firstLinkedList.push(6) 56 | firstLinkedList.push(3) 57 | firstLinkedList.push(5) 58 | firstLinkedList.push(7) 59 | 60 | print "first LinkedList is" 61 | firstLinkedList.printList() 62 | 63 | secondLinkedList.push(4) 64 | secondLinkedList.push(5) 65 | 66 | print "second list is " 67 | print secondLinkedList.printList() 68 | 69 | res = LinkedList() 70 | res.addTwoLists(firstLinkedList.head,secondLinkedList.head) 71 | print "REsultant list is " 72 | res.printList() -------------------------------------------------------------------------------- /LINKEDLIST/ll_mergeSort.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.data = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | def append(self,new_data): 10 | new_node = Node(new_data) 11 | new_node.next = self.head 12 | self.head = new_node 13 | 14 | def printList(self): 15 | temp = self.head 16 | while temp: 17 | print temp 18 | temp = temp.next 19 | 20 | def mergeLists(l1,l2): 21 | temp= None 22 | if l1 is None: 23 | return l2 24 | if l2 is None: 25 | return l1 26 | if l1.data <= l2.data: 27 | temp =l1 28 | temp.next = mergeLists(l1.next,l2) 29 | else: 30 | temp = l2 31 | temp.next = mergeLists(l1,l2.next) 32 | return temp 33 | 34 | def mergeSort(head): 35 | if head is None or head.next is None: 36 | return head 37 | l1, l2 = divideLists(head) 38 | l1 = mergeSort(l1) 39 | l2 = mergeSort(l2) 40 | head = mergeLists(l1, l2) 41 | return head 42 | 43 | def divideLists(head): 44 | slow = head #slow is a pointer to reach the mid of linked list 45 | fast = head #fast is a pointer tor reach the end of linked list 46 | if fast: 47 | fast = fast.next 48 | while fast: 49 | fast = fast.next #fast is incremented twice here 50 | if fast: 51 | fast = fast.next 52 | slow = slow.next 53 | mid = slow.next 54 | slow.next = None 55 | return head, mid 56 | if __name__ == '__main__': 57 | ll =LinkedList() 58 | ll.append(20) 59 | ll.append(10) 60 | ll.append(50) 61 | ll.append(40) 62 | print "Before sorting" 63 | ll.printList() 64 | print "after sorting" 65 | ll.head = mergeSort(ll.head) 66 | ll.printList() 67 | -------------------------------------------------------------------------------- /LINKEDLIST/ll_removeLoop.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | def ransom_note(magazine,rasom): 4 | return (Counter(rasom) - Counter(magazine)) == {} 5 | -------------------------------------------------------------------------------- /LINKEDLIST/ll_removeloop2.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.data = data 4 | self.next = None 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def detectAndRemoveLoop(self): 11 | slow_p = fast_p = self.head 12 | while(slow_p and fast_p and fast_p.next): 13 | slow_p = slow_p.next 14 | fast_p = fast_p.next.next 15 | 16 | #if slow_p and fast_p meet at some point then 17 | #there is a loop 18 | if slow_p == fast_p: 19 | self.removeLoop(slow_p) 20 | return 1 21 | return 0 22 | 23 | def removeLoop(self,loop_node): 24 | ptr1 = loop_node 25 | ptr2 = loop_node 26 | 27 | k=1 28 | while(ptr1.next != ptr2): 29 | ptr1 = ptr1.next 30 | k +=1 31 | 32 | #Fixing one pointer to head 33 | ptr1 = self.head 34 | 35 | ptr2 = self.head 36 | #Add another pointer to k nodes after head 37 | for i in range(k): 38 | ptr2 = ptr2.next 39 | 40 | #Move both pointer at same pace ,they will meet at loop starting point 41 | while (ptr2 != ptr1): 42 | ptr1 = ptr1.next 43 | ptr2 = ptr2.next 44 | 45 | 46 | #get pointer to last node 47 | ptr2 = ptr2.next 48 | while(ptr2.next != ptr1): 49 | ptr2 = ptr2.next 50 | 51 | ptr2.next = None 52 | 53 | def push(self,new_data): 54 | new_node = Node(new_data) 55 | new_node.next = self.head 56 | self.head = new_node 57 | 58 | def printList(self): 59 | temp = self.head 60 | while temp: 61 | print temp.data 62 | temp = temp.next 63 | 64 | 65 | ll = LinkedList() 66 | ll.push(10) 67 | ll.push(3) 68 | ll.push(15) 69 | ll.push(20) 70 | ll.push(50) 71 | 72 | #creating a loop for testing 73 | ll.head.next.next.next.next.next = ll.head.next.next 74 | 75 | ll.detectAndRemoveLoop() 76 | 77 | print "Linked List after removing Loop" 78 | ll.printList() 79 | -------------------------------------------------------------------------------- /LINKEDLIST/ll_start.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | """Fucntion to intialize the Node object""" 3 | def __init__(self,data): 4 | self.data = data #Assign data 5 | self.next = None #Intialize next as None 6 | 7 | class LinkedList(object): 8 | """Function to intialize node head""" 9 | def __init__(self): 10 | self.head = None 11 | def printlist(self): 12 | temp = self.head 13 | while(temp): 14 | print temp.data 15 | temp =temp.next 16 | 17 | if __name__ =='__main__': 18 | #start with the empty list 19 | ll=LinkedList() 20 | ll.head = Node(1) 21 | second = Node(2) 22 | third = Node(3) 23 | 24 | ll.head.next = second 25 | second.next = third 26 | ll.printlist() 27 | -------------------------------------------------------------------------------- /LINKEDLIST/ll_swapping.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.data = data 4 | self.next = None 5 | class LinkedList: 6 | def __init__(self): 7 | self.head = None 8 | def push(self,new_data): 9 | new_node = Node(new_data) 10 | new_node.next = self.head 11 | self.head = new_node 12 | def swap(self,x,y): 13 | if x is None or y is None: 14 | return 15 | if x == y: 16 | return 17 | #Kepping track of previous and current Node 18 | prevX = None 19 | currX= self.head 20 | 21 | prevY = None 22 | currY = self.head 23 | 24 | while (currX != None and currX.data != x): 25 | prevX = currX 26 | currX = currX.next 27 | while (currY != None and currY.data != y): 28 | prevY = currY 29 | currY = currY.next 30 | #if either x or y is not present, nothing to do 31 | if currX == None or currY == None: 32 | return 33 | #if x is not head of the LinkedList 34 | if prevX !=None: 35 | prevX.next = currY 36 | else: 37 | self.head = currY 38 | #if y is not the head of the LinkedList 39 | if prevY !=None: 40 | prevY.next = currX 41 | else: 42 | self.head = currX 43 | #swap the next pointers 44 | temp = currX.next 45 | currX.next = currY.next 46 | currY.next = temp 47 | def push(self,new_data): 48 | new_node = Node(new_data) 49 | new_node.next = self.head 50 | self.head = new_node 51 | 52 | def print_list(self): 53 | temp = self.head 54 | while(temp): 55 | print temp.data 56 | temp =temp.next 57 | #MAin program to test above function 58 | ll =LinkedList() 59 | 60 | ll.push(1) 61 | ll.push(2) 62 | ll.push(3) 63 | ll.push(4) 64 | ll.push(5) 65 | print "LinkedList before swapping " 66 | ll.print_list() 67 | print "LinkedList after swapping " 68 | ll.swap(3,5) 69 | ll.print_list() 70 | -------------------------------------------------------------------------------- /LinkedList/Add-LinkedList-as-no.py: -------------------------------------------------------------------------------- 1 | def SumLinkedList(first,second): 2 | prev = None 3 | temp = None 4 | carry = 0 5 | head = ListNode(0) 6 | while first or second: 7 | fdata = 0 if first is None else first.data 8 | sdata = 0 if second is None else second.data 9 | 10 | sum_ = carry + fdata + sdata 11 | carry = 1 if sum_ >= 10 else 0 12 | 13 | sum_ = sum_ if sum_<10 else sum_%10 14 | temp = Node(sum_) 15 | 16 | if head is None: 17 | head = temp 18 | else: 19 | prev.next = temp 20 | prev = temp 21 | 22 | if first: 23 | first = first.next 24 | if second: 25 | second = second.next 26 | 27 | if carry > 0: 28 | temp.next = Node(carry) 29 | return head 30 | -------------------------------------------------------------------------------- /LinkedList/Deleting-node-in-O(1).py: -------------------------------------------------------------------------------- 1 | ''' 2 | Delete a node from a singly-linked list, ↴ given only a variable pointing to that node. 3 | ''' 4 | def delete_node(node_to_delete): 5 | next_node = node_to_delete.next 6 | 7 | if next_node: 8 | node_to_delete.val = next_node.val 9 | node_to_delete.next = next_node.next 10 | 11 | else: 12 | raise Exception("Can't delete it dude") 13 | -------------------------------------------------------------------------------- /LinkedList/List-Cycle.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution: 8 | # @param A : head node of linked list 9 | # @return the first node in the cycle in the linked list 10 | def detectCycle(self, head): 11 | slow = fast = head 12 | while fast and fast.next: 13 | slow = slow.next 14 | fast = fast.next.next 15 | if slow == fast: 16 | break 17 | else: 18 | return None 19 | while head != slow: 20 | slow = slow.next 21 | head = head.next 22 | return head 23 | -------------------------------------------------------------------------------- /LinkedList/Merge-Lists.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Merge two sorted linked lists and return it as a new list. 3 | The new list should be made by splicing together the nodes of the first two lists, and should also be sorted. 4 | 5 | For example, given following linked lists : 6 | 7 | 5 -> 8 -> 20 8 | 4 -> 11 -> 15 9 | The merged list should be : 10 | 11 | 4 -> 5 -> 8 -> 11 -> 15 -> 20 12 | ''' 13 | def merge(h1,h2): 14 | if None in (h1,h2): 15 | return h1 or h2 16 | dummy = head = ListNode(0) 17 | while h1 and h2: 18 | if h1.val < h2.val: 19 | head.next = h1 20 | head = h1 21 | h1 = h1.next 22 | else: 23 | head.next = h2 24 | head = h2 25 | h2 = h2.next 26 | 27 | head.next = h1 or h2 28 | return dummy.next 29 | -------------------------------------------------------------------------------- /LinkedList/Palindrome-List.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a singly linked list, determine if its a palindrome. Return 1 or 0 denoting if its a palindrome or not, respectively. 3 | 4 | Notes: 5 | 6 | Expected solution is linear in time and constant in space. 7 | For example, 8 | 9 | List 1-->2-->1 is a palindrome. 10 | List 1-->2-->3 is not a palindrome. 11 | ''' 12 | def isPalindrome(self,head): 13 | slow = fast = head 14 | while fast and fast.next: 15 | slow = slow.next 16 | fast = fast.next.next 17 | prev = None 18 | while slow: 19 | next = slow.next 20 | slow.next = prev 21 | prev = slow 22 | slow = next 23 | while prev: 24 | if prev.val != head.val: 25 | return 0 26 | prev = prev.next 27 | head = head.next 28 | return 1 29 | -------------------------------------------------------------------------------- /LinkedList/Remove-Duplicates-ii.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. 3 | 4 | For example, 5 | Given 1->2->3->3->4->4->5, return 1->2->5. 6 | Given 1->1->1->2->3, return 2->3. 7 | 8 | See Expected Output 9 | ''' 10 | def removeDuplicates(self,head): 11 | dummy = prev = ListNode(0) 12 | dummy.next = head 13 | while head and head.next: 14 | if head.val == head.next.val: 15 | while head and head.next and head.val == head.next.val: 16 | head = head.next 17 | head = head.next 18 | prev.next = head 19 | else: 20 | prev = prev.next 21 | head = head.next 22 | return dummy.next 23 | s 24 | -------------------------------------------------------------------------------- /LinkedList/Remove-Duplicates.py: -------------------------------------------------------------------------------- 1 | def removeDuplicates(head): 2 | curr = head 3 | while curr: 4 | while curr.next and curr.next.val == curr.val: 5 | curr.next = curr.next.next 6 | curr = curr.next 7 | return head 8 | -------------------------------------------------------------------------------- /LinkedList/Remove-Nth-Node.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution: 8 | def removeNthFromEnd(self, head, n): 9 | fast = slow = head 10 | for _ in range(n): 11 | fast = fast.next 12 | if not fast: 13 | return head.next 14 | while fast.next: 15 | fast = fast.next 16 | slow = slow.next 17 | slow.next = slow.next.next 18 | return head 19 | -------------------------------------------------------------------------------- /LinkedList/Reorder-List.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution: 8 | # @param A : head node of linked list 9 | # @return the head node in the linked list 10 | def reorderList(self, head): 11 | if head is None: 12 | return None 13 | p = head 14 | q = head 15 | # slow pointer p and quick pointer q 16 | while q is not None and q.next is not None: 17 | q = q.next.next 18 | p = p.next 19 | # find middle 20 | mid = p.next 21 | p.next = None 22 | begin = head 23 | end = mid 24 | pre = None 25 | # reverse link 26 | while end is not None: 27 | temp = end.next 28 | end.next = pre 29 | pre = end 30 | end = temp 31 | # merge link 32 | while pre is not None and begin is not None: 33 | a = pre.next 34 | b = begin.next 35 | begin.next = pre 36 | pre.next = b 37 | begin = b 38 | pre = a 39 | return head 40 | -------------------------------------------------------------------------------- /LinkedList/Reverse-LinkedList-ii.py: -------------------------------------------------------------------------------- 1 | def reverseBetween(head, m, n): 2 | if m == n: 3 | return head 4 | dummyNode = ListNode(0) 5 | dummyNode.next = head 6 | prev = dummyNode 7 | 8 | for i in range(m-1): 9 | prev = prev.next 10 | 11 | rev = None 12 | curr = prev.next 13 | 14 | for i in range(n-m+1): 15 | next = curr.next 16 | curr.next = rev 17 | rev = curr 18 | curr = next 19 | prev.next.next = curr 20 | prev.next = reverse 21 | return dummyNode.next 22 | -------------------------------------------------------------------------------- /LinkedList/Rotate-List.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a list, rotate the list to the right by k places, where k is non-negative. 3 | 4 | For example: 5 | 6 | Given 1->2->3->4->5->NULL and k = 2, 7 | return 4->5->1->2->3->NULL. 8 | ''' 9 | def rotate(self,k,head): 10 | if k == 0: 11 | return head 12 | count = 1 13 | curr = head 14 | while count < k and curr is not None: 15 | curr = curr.next 16 | count += 1 17 | if curr is None: 18 | return head 19 | 20 | kthNode = curr 21 | 22 | while curr.next is not None: 23 | curr = curr.next 24 | curr.next = head 25 | 26 | head = kthNode.next 27 | 28 | kthNode.next = None 29 | 30 | return head 31 | -------------------------------------------------------------------------------- /LinkedList/Sort-List.py: -------------------------------------------------------------------------------- 1 | '''Sort a linked list in O(n log n) time using constant space complexity.''' 2 | def merge(self,h1,h2): 3 | dummy = tail = ListNode(0) 4 | while h1 and h2: 5 | if h1.val < h2.val: 6 | tail.next = h1 7 | tail = h1 8 | h1 = h1.next 9 | else: 10 | tail.next = h2 11 | tail = h2 12 | h2 = h2.next 13 | tail.next = h1 or h2 14 | return dummy.next 15 | def sortList(head): 16 | if head or head.next: 17 | return head 18 | prev, slow, fast = None, head, head 19 | while fast and fast.next: 20 | prev, slow, fast = slow, slow.next, fast.next.next 21 | prev.next = None 22 | return self.merge(self.sort(head),self.sort(slow)) 23 | -------------------------------------------------------------------------------- /LinkedList/Swap-List-nodes-in-pairs.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a linked list, swap every two adjacent nodes and return its head. 3 | 4 | For example, 5 | Given 1->2->3->4, you should return the list as 2->1->4->3. 6 | 7 | Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. 8 | ''' 9 | #Approach 1 10 | def swapPairs(self, head): 11 | pre, pre.next = self, head 12 | while pre.next and pre.next.next: 13 | a = pre.next 14 | b = a.next 15 | pre.next, b.next, a.next = b, a, b.next 16 | pre = a 17 | return self.next 18 | 19 | 20 | #Approach 2 21 | def swapPairs(head): 22 | curr = head 23 | nxt = head.next 24 | while curr and nxt: 25 | curr.val, nxt.val = nxt.val, curr.val 26 | curr = nxt.next 27 | if curr: 28 | nxt = curr.next 29 | return head 30 | -------------------------------------------------------------------------------- /Math/Binary-Representation.py: -------------------------------------------------------------------------------- 1 | #Given a number N >= 0, find its representation in binary. 2 | 3 | def findDigitsInBinary(self, n): 4 | lis = [0]*n 5 | i = 0 6 | if n == 1: 7 | 8 | return 1 9 | if n == 0: 10 | return 0 11 | while(n>0): 12 | lis[i] = n%2 13 | n=n/2 14 | i +=1 15 | lis = lis[:i] 16 | 17 | a = ''.join(map(str,lis[::-1])) 18 | return a 19 | 20 | -------------------------------------------------------------------------------- /Math/DigitLCM.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a number n, find LCM of its digits. 3 | ''' 4 | def gcd(x,y): 5 | while y: 6 | x, y = y, x%y 7 | return x 8 | 9 | def lcm(x,y): 10 | lcm_ = x*y//gcd(x,y) 11 | return lcm_ 12 | 13 | def digitLCM(n): 14 | lcmd = 1 15 | while n > 0: 16 | lcmd = lcm(n%10, lcmd) 17 | if lcmd == 0: 18 | return 0 19 | n = n/10 20 | return lcmd 21 | 22 | n = 397 23 | print digitLCM(n) 24 | -------------------------------------------------------------------------------- /Math/FizzBuzz.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a positive integer N, print all the integers from 1 to N. But for multiples of 3 print “Fizz” instead of the number and for the multiples of 5 print “Buzz”. Also for number which are multiple of 3 and 5, prints “FizzBuzz”. 3 | ''' 4 | class Solution: 5 | # @param A : integer 6 | # @return a list of strings 7 | def fizzBuzz(self, num): 8 | 9 | lis = [] 10 | for i in range(1,num+1): 11 | if i%3 == 0 and i%5 == 0: 12 | lis.append("FizzBuzz") 13 | elif i%3 == 0: 14 | lis.append("Fizz") 15 | elif i%5 == 0: 16 | lis.append("Buzz") 17 | else: 18 | lis.append(i) 19 | return lis 20 | -------------------------------------------------------------------------------- /Math/Greates-common-divisor.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given 2 non negative integers m and n, find gcd(m, n) 3 | 4 | GCD of 2 integers m and n is defined as the greatest integer g such that g is a divisor of both m and n. 5 | Both m and n fit in a 32 bit signed integer. 6 | ''' 7 | def gcd(a,b): 8 | if a < b: 9 | a, b = b, a 10 | while b: 11 | a, b = b, a%b 12 | return a 13 | -------------------------------------------------------------------------------- /Math/Grid-unique-paths.py: -------------------------------------------------------------------------------- 1 | '''A robot is located at the top-left corner of an A x B grid 2 | The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below). 3 | 4 | How many possible unique paths are there? 5 | 6 | 7 | ''' 8 | def uniquePaths(a,b): 9 | if a ==1 or b == 1: 10 | return 1 11 | return uniquePaths(a-1,b) +uniquePaths(a,b-1) 12 | a = 3 13 | b = 3 14 | print uniquePaths(a,b) 15 | -------------------------------------------------------------------------------- /Math/Horner-Method-Polynomial-Evaluation.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Horner’s method can be used to evaluate polynomial in O(n) time. To understand the method, let us consider the example of 2x3 – 6x2 + 2x – 1. The polynomial can be evaluated as ((2x – 6)x + 2)x – 1. The idea is to initialize result as coefficient of xn which is 2 in this case, repeatedly multiply result with x and add next coefficient to result. Finally return result. 3 | ''' 4 | def horner(arr,n,x): 5 | res = arr[0] 6 | for i in range(1,n): 7 | res = res*x + arr[i] 8 | return res 9 | -------------------------------------------------------------------------------- /Math/MagicNumber.py: -------------------------------------------------------------------------------- 1 | def sieve(n): 2 | prime = [True]*(n+1) 3 | p =2 4 | lis=[] 5 | while(p*p 1 and A > 0. A and P both should be integers. 3 | ''' 4 | import math 5 | def power(n): 6 | if n == 1: 7 | return True 8 | for x in range(2,int(math.sqrt(n))+1): 9 | y = 2 10 | while( x**y <= n): 11 | if x**y == n: 12 | return True 13 | else: 14 | y += 1 15 | return False 16 | 17 | print power(8) 18 | -------------------------------------------------------------------------------- /Math/Prime-Numbers.py: -------------------------------------------------------------------------------- 1 | #Find All prime numbers upto a given number n 2 | def sieve(n): 3 | 4 | prime = [True]*(n+1) 5 | p =2 6 | lis=[] 7 | while(p*p = 1: 28 | f = f*n 29 | n = n-1 30 | return f 31 | 32 | def findSmallerInRight(st,low,high): 33 | countRight = 0 34 | i = low + 1 35 | while i <= high: 36 | if st[i] < st[low]: 37 | countRight += 1 38 | i = i + 1 39 | return countRight 40 | 41 | mul = fact(len(st)) 42 | rank = 1 43 | i = 0 44 | while i < len(st): 45 | mul = mul/(len(st)-i) 46 | #count no of chars smaller than str[i] from str[i+1] to str[len-1] 47 | countRight = findSmallerInRight(st,i,len(st)-1) 48 | rank = rank + countRight*mul 49 | i = i+1 50 | for i in set(st): 51 | if st.count(i) > 1: 52 | rank =rank/fact(st.count(i)) 53 | 54 | return rank%1000003 55 | -------------------------------------------------------------------------------- /Math/Sum-of-pairwise-hamming-distance.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Hamming distance between two non-negative integers is defined as the number of positions at which the corresponding bits are different. 3 | 4 | For example, 5 | 6 | HammingDistance(2, 7) = 2, as only the first and the third bit differs in the binary representation of 2 (010) and 7 (111). 7 | 8 | Given an array of N non-negative integers, find the sum of hamming distances of all pairs of integers in the array. 9 | Return the answer modulo 1000000007. 10 | ''' 11 | class Solution: 12 | # @param A : tuple of integers 13 | # @return an integer 14 | def hammingDistance(self, arr): 15 | 16 | n = len(arr) 17 | ans = 0 18 | for i in range(32): 19 | count = 0 20 | for j in range(n): 21 | if (arr[j] & (1 << i)): 22 | count +=1 23 | ans += (count*(n-count)*2) 24 | return ans%1000000007 25 | -------------------------------------------------------------------------------- /Math/Sum_of_Multiples.py: -------------------------------------------------------------------------------- 1 | '''Given a number a and limit N. Find the sum of multiple of a upto N.''' 2 | #Simple Iterative O(n) Approach 3 | def sumUpto(a,n): 4 | sum_ = 0 5 | i = a 6 | while i <= n: 7 | sum_ += i 8 | i += a 9 | return sum_ 10 | 11 | print sumUpto(7,49) 12 | 13 | 14 | #Another O(1) Approach 15 | def sumUpto(a,n): 16 | m = n/a 17 | sum_ = m*(m+1)/2 18 | ans = a*sum_ 19 | return ans 20 | 21 | print sumUpto(7,49) 22 | -------------------------------------------------------------------------------- /Math/Verify-Prime.py: -------------------------------------------------------------------------------- 1 | '''Given a number n ,verify if n is prime or not''' 2 | def isPrime(self, n): 3 | if n == 2 or n == 3: 4 | return 1 5 | if n== 1: 6 | return 0 7 | if (n%2 == 0 or n%3 == 0): 8 | return 0 9 | 10 | for i in range(5,int(math.sqrt(n))+1,6): 11 | if n%i ==0 or n%(i+2) ==0: 12 | return 0 13 | return 1 14 | -------------------------------------------------------------------------------- /Math/excel-column-number.py: -------------------------------------------------------------------------------- 1 | 2 | # Time: O(n) 3 | # Space: O(1) 4 | 5 | # Related to question Excel Sheet Column Title 6 | # 7 | # Given a column title as appear in an Excel sheet, return its corresponding column number. 8 | # 9 | # For example: 10 | # 11 | # A -> 1 12 | # B -> 2 13 | # C -> 3 14 | # ... 15 | # Z -> 26 16 | # AA -> 27 17 | # AB -> 28 18 | def titleToNumber(num): 19 | res = 0 20 | for i in range(len(num)): 21 | res *=26 22 | res += ord(num[i])-ord('A')+1 23 | return result 24 | 25 | print titleToNumber("AB") 26 | -------------------------------------------------------------------------------- /Math/largest-coprime-divisor.py: -------------------------------------------------------------------------------- 1 | ''' 2 | You are given two positive numbers A and B. You need to find the maximum valued integer X such that: 3 | 4 | X divides A i.e. A % X = 0 5 | X and B are co-prime i.e. gcd(X, B) = 1 6 | ''' 7 | def gcd(a, b): 8 | while b: 9 | a, b = b, a%b 10 | return a 11 | 12 | class Solution: 13 | # @param A : integer 14 | # @param B : integer 15 | # @return an integer 16 | def cpFact(self, A, B): 17 | p=gcd(A,B) 18 | while p!=1: 19 | A/=p 20 | p=gcd(A,B) 21 | return A 22 | -------------------------------------------------------------------------------- /Math/primeNumberDifference.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given two integers find the maximum difference between two prime numbers contained in their range. For e.g. if you are given two integers 2 and 6, i.e range [2,6] inclusive, the two farthest prime numbers are 2 & 5 and the answer is 3. If there are no prime numbers in the range, print 0. 3 | ''' 4 | from bisect import bisect_left, bisect_right 5 | N = 10**6 6 | def getPrimes(N): 7 | primes = [2] 8 | check = [1] * N 9 | for i in range(3,N,2): 10 | if check[i]: 11 | primes.append(i) 12 | for j in range(3*i,N,2*i): 13 | check[j] = 0 14 | return primes 15 | 16 | primes = getPrimes(N) 17 | t = int(raw_input()) 18 | for i in range(t): 19 | n1, n2 = map(int,raw_input().split()) 20 | i1 = bisect_right(primes,n1) 21 | i2 = bisect_left(primes,n2) 22 | if i1 > 0 and primes[i1-1] == n1: 23 | i1 -= 1 24 | while i2 > 0 and primes[i2] > n2: 25 | i2 -= 1 26 | 27 | if i2 + 1 < len(primes) and primes[i2+1] <= n2: 28 | i2 += 1 29 | p1 = primes[i1] 30 | p2 = primes[i2] 31 | #print p1, p2 32 | if p1 < p2: 33 | print p2-p1 34 | else: 35 | print 0 36 | -------------------------------------------------------------------------------- /Math/reverse-integer.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A : integer 3 | # @return an integer 4 | def reverse(self, A): 5 | 6 | if -10 < A < 10: 7 | return A 8 | 9 | ans = int(str(A).lstrip('-')[::-1]) 10 | ans = -1 * ans if A < 0 else ans 11 | 12 | if not (-2147483648 < ans < 2147483647): 13 | return 0 14 | else: 15 | return ans 16 | -------------------------------------------------------------------------------- /Math/sorted-permutations-rank-with-repeats.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | class Solution: 3 | 4 | def fact (self, n ) : 5 | if n <= 1 : 6 | return 1 7 | else : 8 | return n * self.fact(n-1) 9 | 10 | def findRank(self, A): 11 | 12 | res = 1 13 | char_occur = {} 14 | for char in A: 15 | char_occur[char] = char_occur.get(char, 0) + 1 16 | for i in range(0, len(A)-1) : 17 | rank = 0 18 | for j in range(i+1, len(A)) : 19 | if A[i] > A[j] : 20 | rank += 1 21 | temp = self.fact(len(A) - i - 1)%1000003 22 | temp1= 1 23 | for key in char_occur.keys() : 24 | temp1 *= self.fact(char_occur[key]) 25 | temp1 = pow(temp1, 1000001, 1000003) 26 | res = (res + rank * temp1 * temp)%1000003 27 | char_occur[A[i]] -= 1 28 | return res 29 | 30 | ''' 31 | Another Solution 32 | ''' 33 | def fact(n) : 34 | f = 1 35 | while n >= 1 : 36 | f = f * n 37 | n = n - 1 38 | return f 39 | 40 | # A utility function to count smaller 41 | # characters on right of arr[low] 42 | def findSmallerInRight(st, low, high) : 43 | 44 | countRight = 0 45 | i = low + 1 46 | while i <= high : 47 | if st[i] < st[low] : 48 | countRight = countRight + 1 49 | i = i + 1 50 | 51 | return countRight 52 | 53 | # A function to find rank of a string 54 | # in all permutations of characters 55 | def findRank (st) : 56 | ln = len(st) 57 | mul = fact(ln) 58 | rank = 1 59 | i = 0 60 | 61 | while i < ln : 62 | 63 | mul = mul / (ln - i) 64 | 65 | # count number of chars smaller 66 | # than str[i] fron str[i+1] to 67 | # str[len-1] 68 | countRight = findSmallerInRight(st, i, ln-1) 69 | 70 | rank = rank + countRight * mul 71 | i = i + 1 72 | for j in set(st): 73 | if st.count(j) > 1: 74 | rank = rank/fact(st.count(j)) 75 | return rank + 1 76 | 77 | 78 | # Driver program to test above function 79 | st = "aba" 80 | print (findRank(st)) 81 | -------------------------------------------------------------------------------- /Matrix/Print-Matrix-Z-Form.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a square matrix of order n*n, we need to print elements of the matrix in Z form 3 | ''' 4 | def PrintZ(arr): 5 | #Printing first row 6 | for i in range(0,len(arr)): 7 | print arr[0][i], 8 | 9 | #Printing diagonal elements 10 | k = 1 11 | for i in range(0,n): 12 | for j in range(n,0,-1): 13 | if (j == n-k): 14 | print arr[i][j], 15 | break 16 | k +=1 17 | i = n-1 18 | for j in range(0,n): 19 | print arr[i][j], 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | # InterviewBit Solutions 6 | 7 | 8 | ![languages-Python%20&%20C++-orange.svg](https://img.shields.io/badge/languages-Python%20&%20C++-orange.svg) [![License-GNU-red.svg](https://img.shields.io/badge/License-GNU-red.svg)](https://img.shields.io/badge/License-GNU-red.svg) 9 | ======= 10 | 11 | This is a repository of solutions to all problems I've solved on InterviewBit. I am not quite sure exactly how many problems there are on the website, but I'll be updating this with every problem I solve. Please issue a pull request if you think you have a better solution or something I could improve upon. 12 | 13 | # Topics 14 | 15 | * [Time Complexity](#) 16 | * [Arrays](https://github.com/rahulcode22/Data-structures/tree/master/Arrays) 17 | * [Math](https://github.com/rahulcode22/Data-structures/tree/master/Math) 18 | * [Binary Search](https://github.com/rahulcode22/Data-structures/tree/master/Binary-Search) 19 | * [String](https://github.com/rahulcode22/Data-structures/tree/master/String) 20 | * [Stack and Queue](#) 21 | * [Bit Manipulation](https://github.com/rahulcode22/Data-structures/tree/master/Bit-Manipulation) 22 | * [Two Pointers](https://github.com/rahulcode22/Data-structures/tree/master/Two-Pointers) 23 | * [Backtracking](https://github.com/rahulcode22/Data-structures/tree/master/Backtracking) 24 | * [Linked List](https://github.com/rahulcode22/Data-structures/tree/master/Linked-List) 25 | * [Trees](https://github.com/rahulcode22/Data-structures/tree/master/Trees) 26 | * [Dynamic Programming](https://github.com/rahulcode22/Data-structures/tree/master/Dynamic-Programming) 27 | * [Greedy](https://github.com/rahulcode22/Data-structures/tree/master/Greedy) 28 | -------------------------------------------------------------------------------- /Stack/Balanced-Expression.py: -------------------------------------------------------------------------------- 1 | class Stack: 2 | def __init__(self): 3 | self.items = [] 4 | 5 | #Push a new item to the last index 6 | def push(self,item): 7 | self.items.append(item) 8 | 9 | #Remove the last item 10 | def pop(self): 11 | #if stack is empty 12 | if not self.items: 13 | return None 14 | return self.items.pop() 15 | 16 | def peek(self): 17 | if not self.items: 18 | return None 19 | return self.items[-1] 20 | 21 | def isEmpty(self): 22 | return self.items == [] 23 | 24 | def isBalanced(expression): 25 | s = Stack() 26 | balanced = True 27 | index = 0 28 | while index < len(expression) and balanced: 29 | symbol = expression[index] 30 | if symbol == "(": 31 | s.push(symbol) 32 | else: 33 | if s.isEmpty(): 34 | balanced = False 35 | else: 36 | s.pop() 37 | index += 1 38 | if balanced and s.isEmpty(): 39 | return True 40 | else: 41 | return False 42 | 43 | print isBalanced('(())') 44 | 45 | 46 | 47 | '''Balanced Expressiom for general Case''' 48 | class Stack: 49 | def __init__(self): 50 | self.items = [] 51 | 52 | #Push a new item to the last index 53 | def push(self,item): 54 | self.items.append(item) 55 | 56 | #Remove the last item 57 | def pop(self): 58 | #if stack is empty 59 | if not self.items: 60 | return None 61 | return self.items.pop() 62 | 63 | def peek(self): 64 | if not self.items: 65 | return None 66 | return self.items[-1] 67 | 68 | def isEmpty(self): 69 | return self.items == [] 70 | 71 | def isBalanced(expression): 72 | s = Stack() 73 | balanced = True 74 | index = 0 75 | while index < len(expression) and balanced: 76 | symbol = expression[index] 77 | if symbol in "({[": 78 | s.push(symbol) 79 | else: 80 | top = s.pop() 81 | if not matches(top,symbol): 82 | balanced = False 83 | index += 1 84 | if balanced and s.isEmpty(): 85 | return True 86 | else: 87 | return False 88 | 89 | def matches(open,close): 90 | opens = "([{" 91 | closers = ")]}" 92 | return opens.index(open) == closers.index(close) 93 | 94 | print isBalanced('{([])}') 95 | -------------------------------------------------------------------------------- /Stack/Equal-Stack.py: -------------------------------------------------------------------------------- 1 | ''' 2 | You have three stacks of cylinders where each cylinder has the same diameter, but they may vary in height. You can change the height of a stack by removing and discarding its topmost cylinder any number of times. 3 | 4 | Find the maximum possible height of the stacks such that all of the stacks are exactly the same height. This means you must remove zero or more cylinders from the top of zero or more of the three stacks until they're all the same height, then print the height. The removals must be performed in such a way as to maximize the height. 5 | ''' 6 | n1, n2, n3 = map(int,raw_input().split(' ')) 7 | h1 = map(int,raw_input().split())[::-1] 8 | h2 = map(int,raw_input().split())[::-1] 9 | h3 = map(int,raw_input().split())[::-1] 10 | 11 | sum_h1 = sum(h1) 12 | sum_h2 = sum(h2) 13 | sum_h3 = sum(h3) 14 | 15 | while not ((sum_h3 == sum_h2) and (sum_h1 == sum_h2)): 16 | 17 | if sum_h1 > sum_h2 and sum_h1 > sum_h3: 18 | t = h1.pop() 19 | sum_h1 -= t 20 | 21 | if sum_h1 < sum_h2 and sum_h2 > sum_h3: 22 | t = h2.pop() 23 | sum_h2 -= t 24 | 25 | if sum_h1 < sum_h3 and sum_h2 < sum_h3: 26 | t = h3.pop() 27 | sum_h3 -= t 28 | 29 | print sum_h1 30 | -------------------------------------------------------------------------------- /Stack/Introduction: -------------------------------------------------------------------------------- 1 | -->It is a linear data structure. 2 | -->Follows a paarticular order in which the operations are performed.' 3 | -->Order may be FILO or LIFO 4 | -->Main operations are 5 | 1)push-->Add an item in the stack 6 | 2)pop-->removes an item in the stack 7 | 3)peek-->get the topmost item. 8 | -->stack may be implemented using two ways: 9 | 1)using linked list 10 | 2)using arrays 11 | -------------------------------------------------------------------------------- /Stack/Introduction.py: -------------------------------------------------------------------------------- 1 | '''-->It is a linear data structure. 2 | -->Follows a paarticular order in which the operations are performed.' 3 | -->Order may be FILO or LIFO 4 | -->Main operations are 5 | 1)push-->Add an item in the stack 6 | 2)pop-->removes an item in the stack 7 | 3)peek-->get the topmost item. 8 | -->stack may be implemented using two ways: 9 | 1)using linked list 10 | 2)using arrays 11 | ''' 12 | from sys import maxsize 13 | #fucntion to create Stack 14 | def createStack(): 15 | stack = [] 16 | return stack 17 | 18 | def isEmpty(stack): 19 | return len(stack) == 0 20 | 21 | def push(stack,item): 22 | stack.append(item) 23 | print "pushed to stack" + item 24 | 25 | def pop(stack): 26 | if isEmpty(stack): 27 | return str(-maxsize-1) 28 | return stack.pop() 29 | 30 | stack = createStack() 31 | push(stack,str(10)) 32 | push(stack,str(20)) 33 | push(stack,str(30)) 34 | push(stack,str(40)) 35 | print pop(stack) + "Popped from stack" 36 | 37 | 38 | 39 | 40 | 41 | 42 | #Implementing stack using linkedList 43 | class StackNode: 44 | def __init__(self,data): 45 | self.data = data 46 | self.next = None 47 | 48 | class Stack: 49 | def __init__(self): 50 | self.root = None 51 | 52 | def isEmpty(self): 53 | return True is self.root is None else False 54 | 55 | def push(self,data): 56 | new_node = StackNode(data) 57 | new_node.next = self.root 58 | self.root = new_node 59 | 60 | def pop(self): 61 | if self.isempty(): 62 | return float("-inf") 63 | temp = self.root 64 | self.root = self.root.next 65 | Popped = temp.data 66 | return Popped 67 | 68 | def peek(self): 69 | if self.isEmpty(): 70 | return float("-inf") 71 | return self.root.data 72 | 73 | #Driver program to test above class 74 | stack = Stack() 75 | stack.push(10) 76 | stack.push(20) 77 | stack.push(30) 78 | print "%d popped from stack" %(stack.pop()) 79 | 80 | print "Top element is %d" % (stack.peek()) 81 | -------------------------------------------------------------------------------- /Stack/Largest-Stack.py: -------------------------------------------------------------------------------- 1 | '''You want to be able to access the largest element in a stack.'''' 2 | class Stack: 3 | def __init__(self): 4 | self.items = [] 5 | 6 | #Push a new item to the last index 7 | def push(self,item): 8 | self.items.append(item) 9 | 10 | #Remove the last item 11 | def pop(self): 12 | #if stack is empty 13 | if not self.items: 14 | return None 15 | return self.items.pop() 16 | 17 | def peek(self): 18 | if not self.items: 19 | return None 20 | return self.items[-1] 21 | 22 | class MaxStack: 23 | def __init__(self): 24 | self.stack = Stack() 25 | self.max_stack = Stack() 26 | 27 | def push(self,item): 28 | self.stack.push(item) 29 | if self.max_stack.peek() is None or item >= self.max_stack.peek(): 30 | self.max_stack.push(item) 31 | 32 | def pop(self): 33 | item = self.stack.pop() 34 | if item == self.max_stack.peek(): 35 | self.max_stack.pop() 36 | return item 37 | 38 | def get_max(self): 39 | return self.max_stack.peek() 40 | -------------------------------------------------------------------------------- /Stack/Queue-using-two-stack.py: -------------------------------------------------------------------------------- 1 | class QueueTwoStacks: 2 | def __init__(self): 3 | self.in_stack = [] 4 | self.out_stack = [] 5 | 6 | def enqueue(self,item): 7 | self.in_stack.append(item) 8 | 9 | def dequeue(self): 10 | if len(self.out_stack) == 0: 11 | 12 | while self.in_stack: 13 | new_item = self.in_stack.pop() 14 | self.out_stack.append(new_item) 15 | 16 | if len(self.out_stack) == 0: 17 | raise IndexError("Can't dequeue an empty stack") 18 | return self.out_stack.pop() 19 | 20 | s = QueueTwoStacks() 21 | s.enqueue(1) 22 | s.enqueue(2) 23 | s.enqueue(3) 24 | print s.dequeue() 25 | -------------------------------------------------------------------------------- /Stack/Stack Implementation.py: -------------------------------------------------------------------------------- 1 | #Python program for implementation of stack using linked list 2 | #Class to represent node 3 | class Node: 4 | #constructor to intialize node 5 | def __init__(self,data): 6 | self.data=data 7 | self.next=None 8 | 9 | class Stack: 10 | #Constructor to intialize root of linked list 11 | def __init__(self,root): 12 | self.root=None 13 | def isempty(self): 14 | return True if self.root is None else False 15 | def push(data): 16 | newnode=Node(data) 17 | newnode.next=root 18 | root=newnode 19 | def pop(): 20 | if isempty(): 21 | return 0 22 | temp=root 23 | root=root.next 24 | popped=temp.data 25 | return popped 26 | def peek(): 27 | if isempty(): 28 | return 0 29 | return root.data 30 | #program to test above function 31 | stack=stack() 32 | stack.push(5) 33 | stack.push(10) 34 | stack.push(15) 35 | print stack.pop 36 | print stack.peek 37 | 38 | 39 | 40 | #implementing stack using arrays 41 | #import maxsize from sys.Maxsize returns infinite when stack is empty. 42 | from sys import maxsize 43 | #function to create a stack.initial size of stack is zero 44 | def createstack(): 45 | stack=[] 46 | return stack 47 | if isempty(stack): 48 | return len(stack)==0 49 | 50 | #push function to add an item on the stack.Increases stack size by 1 51 | def push(stack,item): 52 | stack.append(item) 53 | print ("item pushed"+item) 54 | #pop function to remove item from stack.Decreases stack size by 1. 55 | def pop(stack): 56 | if (isempty(stack)): 57 | return str(-maxsize-1) 58 | stack.pop() 59 | #peek function.return top element of the stack 60 | def peek(stack): 61 | if (isempty(stack)): 62 | return str(-maxsize-1) 63 | return stack[-len(stack)-1] 64 | #driver program to test the above functions 65 | stack=createstack() 66 | push(stack,str(10)) 67 | push(stack,str(20)) 68 | push(stack,str(30)) 69 | push(stack,str(40)) 70 | print(pop(stack) +" is popped from stack") 71 | print("top item is "+peek(stack)) 72 | 73 | -------------------------------------------------------------------------------- /Stack/evaluateExpression.py: -------------------------------------------------------------------------------- 1 | '''Evaluate the value of an arithmetic expression in Reverse Polish Notation. 2 | 3 | Valid operators are +, -, *, /. Each operand may be an integer or another expression. 4 | 5 | ''' 6 | class Solution: 7 | # @param A : list of strings 8 | # @return an integer 9 | def evalRPN(self, tokens): 10 | stack = [] 11 | for t in tokens: 12 | if t not in ["+", "-", "*", "/"]: 13 | stack.append(int(t)) 14 | else: 15 | r, l = stack.pop(), stack.pop() 16 | if t == "+": 17 | stack.append(l+r) 18 | elif t == "-": 19 | stack.append(l-r) 20 | elif t == "*": 21 | stack.append(l*r) 22 | else: 23 | # here take care of the case like "1/-22", 24 | # in Python 2.x, it returns -1, while in 25 | # Leetcode it should return 0 26 | if l*r < 0 and l % r != 0: 27 | stack.append(l/r+1) 28 | else: 29 | stack.append(l/r) 30 | return stack.pop() 31 | -------------------------------------------------------------------------------- /Stack/implementing two stack.py: -------------------------------------------------------------------------------- 1 | class twostack: 2 | def __init__(self,n): 3 | self.size=n 4 | self.arr=[None]*n 5 | self.top1=-1 6 | top2=size 7 | #pushing item x in stack1 8 | def push1(x): 9 | if top1 < top2-1: 10 | top1 = top1+1 11 | arr[top1] = x 12 | else: 13 | print "stack overflow" 14 | exit(1) 15 | #method to push an element x to stack2 16 | def push2(x): 17 | if top1 < top2-1: 18 | top2 -= 1 19 | arr[top2] = x 20 | else: 21 | print "Stack Overflow" 22 | exit(1) 23 | #method to pop an element from first stack 24 | def pop1(self): 25 | if top1 >= 0: 26 | x = self.arr[self.top1] 27 | top1 = top1-1 28 | return x 29 | else: 30 | print "stack underflow" 31 | exit(1) 32 | def pop2(self): 33 | if top2 <= slf.size: 34 | x = self.array[self.top2] 35 | self.top2 = self.top2+1 36 | return x 37 | else: 38 | print "stack underflow" 39 | exit() 40 | -------------------------------------------------------------------------------- /Stack/infixToPostfix.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 1.Create an empty stack called 'opstack' for keeping operators.Create an empty list for output. 3 | 2.Convert the input infix string to a list using split method. 4 | 3.Scan the token list from left to right. 5 | ->If the token is an operand,apppend it to the end of output list. 6 | ->If token is a left parenthesis, push it on the stack 7 | ->If the token is a right parenthesis, pop the opstack until the corresponding left parenthesis is removed.Append each operator to the end of the output list. 8 | ->If the token is an operator, *,/,+ or -, push it on the opstack.However, first remove any operators already on the opstack that have higher or equal precedence and append them to the output list. 9 | 4.When the input expression has been completely processed, check the opstack.Any operators still on the stack can be removed and appended to the end of the output list. 10 | ''' 11 | class Stack: 12 | def __init__(self): 13 | self.items = [] 14 | 15 | def push(self,item): 16 | self.items.append(item) 17 | 18 | def isEmpty(self): 19 | return self.items == [] 20 | 21 | def pop(self): 22 | if self.isEmpty(): 23 | return None 24 | return self.items.pop() 25 | 26 | def peek(self): 27 | if self.isEmpty(): 28 | return None 29 | return self.items[-1] 30 | 31 | def infixToPostfix(expr): 32 | precedence = {} 33 | precedence["*"] = 3 34 | precedence["/"] = 3 35 | precedence["+"] = 2 36 | precedence["-"] = 2 37 | precedence["("] = 1 38 | opstack = Stack() 39 | postfixList = [] 40 | tokenList = expr.split() 41 | 42 | for token in tokenList: 43 | if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789": 44 | postfixList.append(token) 45 | elif token == '(': 46 | opstack.push(token) 47 | elif token == ')': 48 | topToken = opstack.pop() 49 | while topToken != '(': 50 | postfixList.append(topToken) 51 | topToken = opstack.pop() 52 | else: 53 | while (not opstack.isEmpty()) and precedence[opstack.peek()] >= precedence[token]: 54 | postfixList.append(opstack.pop()) 55 | opstack.push(token) 56 | while not opstack.isEmpty(): 57 | postfixList.append(opstack.pop()) 58 | return " ".join(postfixList) 59 | 60 | print infixToPostfix("A * B + C * D") 61 | -------------------------------------------------------------------------------- /Stack/min-stack.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. 3 | ''' 4 | class MinStack: 5 | stack = [] 6 | minimums = [] 7 | # @param x, an integer 8 | # @return an integer 9 | def push(self, x): 10 | if len(self.stack) == 0: 11 | self.stack.append(x) 12 | self.minimums.append(x) 13 | else: 14 | self.stack.append(x) 15 | if x < self.minimums[-1]: 16 | self.minimums.append(x) 17 | else: 18 | self.minimums.append(self.minimums[-1]) 19 | 20 | # @return nothing 21 | def pop(self): 22 | if len(self.stack) != 0: 23 | self.stack.pop() 24 | self.minimums.pop() 25 | 26 | # @return an integer 27 | def top(self): 28 | if len(self.stack) == 0: 29 | return -1 30 | else: 31 | return self.stack[-1] 32 | 33 | # @return an integer 34 | def getMin(self): 35 | if len(self.stack) == 0: 36 | return -1 37 | else: 38 | return self.minimums[-1] 39 | 40 | def __init__(self): 41 | self.stack = [] 42 | self.minimums = [] 43 | -------------------------------------------------------------------------------- /Stack/nearest-smaller-element.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Given an array, find the nearest smaller element G[i] for every element A[i] in the array such that the element has an index smaller than i. 4 | 5 | 6 | ''' 7 | def smaller(arr): 8 | res = [] 9 | stack = [] 10 | for i in range(len(arr)): 11 | while len(stack) != 0 and stack[-1] >= arr[i]: 12 | stack.pop() 13 | if len(stack) == 0: 14 | res.append(-1) 15 | else: 16 | res.append(stack[-1]) 17 | 18 | stack.append(arr[i]) 19 | return res 20 | 21 | arr = [1,3,0,2,5] 22 | print smaller(arr) 23 | -------------------------------------------------------------------------------- /Stack/redundantBraces.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Write a program to validate if the input string has redundant braces? 3 | Return 0/1 4 | 5 | 0 -> NO 6 | 1 -> YES 7 | ''' 8 | class Solution: 9 | # @param A : string 10 | # @return an integer 11 | def braces(self, A): 12 | stack = [] 13 | for el in A: 14 | if el == "(": 15 | stack.append(el) 16 | elif el == "+" or el == "-" or el == "/" or el == "*": 17 | stack.append("exp") 18 | elif el == ")": 19 | if stack[-1] == "exp": 20 | stack.pop() 21 | stack.pop() 22 | else: 23 | return 1 24 | else: 25 | return 0 26 | -------------------------------------------------------------------------------- /Stack/reverse_string.py: -------------------------------------------------------------------------------- 1 | #python program to print reverse of a string using stack 2 | #Function to create an empty stack 3 | def createstack(): 4 | stack=[] 5 | return stack 6 | #function to get the length of the stack 7 | def length(stack): 8 | return len(stack) 9 | #stack is empty if size is zero 10 | def isempty(stack): 11 | return size(stack)==0 12 | def push(item,stack): 13 | stack.append(item) 14 | def pop(stack): 15 | return stack.pop() 16 | #A stack based function to print reverse of string 17 | def reverse(string): 18 | n=len(string) 19 | #create an empty stack 20 | stack=createstack() 21 | #pushing all characters of string to stack 22 | for i in range(n): 23 | push(stack,string[i]) 24 | #make the string empty 25 | string="" 26 | #now pop all the characters from the string to string 27 | for i in range(n): 28 | string +=pop(stack) 29 | return string 30 | #test above function 31 | string="Python" 32 | string =reverse(string) 33 | print ("reversed string" +string) 34 | -------------------------------------------------------------------------------- /Stack/rpn.py: -------------------------------------------------------------------------------- 1 | def rpn(exp): 2 | stack = [] 3 | for e in exp: 4 | if e not in ["+", "-", "*", "/"]: 5 | stack.append(int(e)) 6 | else: 7 | l, r = stack.pop(), stack.pop() 8 | if e == "+": 9 | stack.append(l+r) 10 | elif e == "-": 11 | stack.append(l-r) 12 | elif e == "*": 13 | stack.append(l*r) 14 | else: 15 | if l*r < 0 and l%r != 0: 16 | stack.append(l/r + 1) 17 | else: 18 | stack.append(l/r) 19 | return stack.pop() 20 | -------------------------------------------------------------------------------- /Stack/simplifydirectoryPath.py: -------------------------------------------------------------------------------- 1 | '''Given an absolute path for a file (Unix-style), simplify it.''' 2 | class Solution(object): 3 | def simplifyPath(self, path): 4 | places = [p for p in path.split("/") if p!="." and p!=""] 5 | stack = [] 6 | for p in places: 7 | if p == "..": 8 | if len(stack) > 0: 9 | stack.pop() 10 | else: 11 | stack.append(p) 12 | return "/" + "/".join(stack) 13 | -------------------------------------------------------------------------------- /String/Add-binary-strings.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Given two binary strings, return their sum (also a binary string). 4 | ''' 5 | class Solution: 6 | # @param A : string 7 | # @param B : string 8 | # @return a strings 9 | def addBinary(self, A, B): 10 | a = int(A,2) 11 | b = int(B,2) 12 | c = bin(a+b)[2:] 13 | return c 14 | -------------------------------------------------------------------------------- /String/Atoi.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A : string 3 | # @return an integer 4 | def atoi(self, string): 5 | if len(string) == 0: 6 | return 0 7 | ls = list(string.strip()) 8 | 9 | sign = -1 if ls[0] == '-' else 1 10 | if ls[0] in ['-','+'] : del ls[0] 11 | ret, i = 0, 0 12 | while i < len(ls) and ls[i].isdigit(): 13 | ret = ret*10 + ord(ls[i]) - ord('0') 14 | i += 1 15 | return max(-2**31, min(sign * ret,2**31-1)) 16 | -------------------------------------------------------------------------------- /String/Count-and-Say.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The count-and-say sequence is the sequence of integers beginning as follows: 3 | 1, 11, 21, 1211, 111221, ... 4 | 1 is read off as one 1 or 11. 5 | 11 is read off as two 1s or 21. 6 | 7 | 21 is read off as one 2, then one 1 or 1211. 8 | 9 | Given an integer n, generate the nth sequence. 10 | 11 | Note: The sequence of integers will be represented as a string. 12 | 13 | Example: 14 | 15 | if n = 2, 16 | the sequence is 11. 17 | 18 | ''' 19 | def countAndSay(n): 20 | s = '1' 21 | for i in range(n-1): 22 | 23 | let ,temp ,count = s[0], '', 0 24 | for l in s: 25 | if let == l: 26 | count += 1 27 | else: 28 | temp += str(count) + let 29 | let = l 30 | count = 1 31 | temp += str(count) + let 32 | s = temp 33 | return s 34 | 35 | print countAndSay(4) 36 | -------------------------------------------------------------------------------- /String/Implement-StrStr.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param haystack : string 3 | # @param needle : string 4 | # @return an integer 5 | def strStr(self, txt, pat): 6 | def computeLPSArray(pat,m,lps): 7 | j = 0 #length of previous lps 8 | lps[0] = 0 9 | i = 1 10 | while i < m: 11 | if pat[i] == pat[j]: 12 | j += 1 13 | lps[i] = j 14 | i += 1 15 | else: 16 | if j != 0: 17 | j = lps[j-1] 18 | else: 19 | lps[i] = 0 20 | i += 1 21 | m = len(pat) 22 | n = len(txt) 23 | #Now create a lps array that will hold the longest prefix suffix value 24 | lps = [0]*m 25 | j = 0 #index for pat 26 | computeLPSArray(pat,m,lps) 27 | 28 | i = 0 #index For txt[] 29 | 30 | while i < n: 31 | if pat[j] == txt[i]: 32 | i += 1 33 | j += 1 34 | if j == m: 35 | return (i-j) 36 | elif i < n and pat[j] != txt[i]: 37 | if j != 0: 38 | j = lps[j-1] 39 | else: 40 | i += 1 41 | return -1 42 | -------------------------------------------------------------------------------- /String/Integer-To-Roman.py: -------------------------------------------------------------------------------- 1 | def integerToRoman(num): 2 | m = ["", "M" ,"MM", "MMM"] 3 | c = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"] 4 | x = ["", "X", "XX", "XXX", "XL", "L" ,"LX", "LXX", "LXXX", "XC"] 5 | i = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"] 6 | thousands = m[num/1000] 7 | hundreds = c[(num%1000)/100] 8 | tens = x[(num%100)/10] 9 | ones = i[num%10] 10 | ans = thousands + hundreds + tens + ones 11 | return ans 12 | 13 | print integerToRoman(3549) 14 | -------------------------------------------------------------------------------- /String/Justified-text.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. 3 | You should pack your words in a greedy approach; that is, pack as many words as you can in each line. 4 | 5 | Pad extra spaces ‘ ‘ when necessary so that each line has exactly L characters. 6 | Extra spaces between words should be distributed as evenly as possible. 7 | If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. 8 | For the last line of text, it should be left justified and no extra space is inserted between words. 9 | 10 | Your program should return a list of strings, where each string represents a single line. 11 | ''' 12 | def justifiedText(words,maxWidth): 13 | if len(words) == 1: 14 | return words[0]*maxWidth 15 | res, cur, num_of_letters = [], [], 0 16 | for w in words: 17 | if num_of_letters + len(w) > maxWidth: 18 | for i in range(maxWidth - num_of_letters): 19 | cur[i%(len(cur)-1 or 1)] += ' ' 20 | res.append(''.join(cur)) 21 | cur, num_of_letters = [], 0 22 | cur += [w] 23 | num_of_letters += len(w) 24 | return res + [' '.join(cur).ljust(maxWidth)] 25 | words = [""] 26 | maxWidth = 10 27 | print justifiedText(words,maxWidth) 28 | -------------------------------------------------------------------------------- /String/KMP-Algo.py: -------------------------------------------------------------------------------- 1 | def KMPSearch(pat,txt): 2 | m = len(pat) 3 | n = len(txt) 4 | #Now create a lps array that will hold the longest prefix suffix value 5 | lps = [0]*m 6 | j = 0 #index for pat 7 | computeLPSArray(pat,m,lps) 8 | 9 | i = 0 #index For txt[] 10 | 11 | while i < n: 12 | if pat[j] == txt[i]: 13 | i += 1 14 | j += 1 15 | if j == m: 16 | print "Pattern found at index" + str(i-j) 17 | j = lps[j-1] 18 | elif i < n and pat[j] != txt[i]: 19 | if j != 0: 20 | j = lps[j-1] 21 | else: 22 | i += 1 23 | 24 | def computeLPSArray(pat,m,lps): 25 | j = 0 #length of previous lps 26 | lps[0] = 0 27 | i = 1 28 | while i < m: 29 | if pat[i] == pat[j]: 30 | j += 1 31 | lps[i] = j 32 | i += 1 33 | else: 34 | if j != 0: 35 | j = lps[j-1] 36 | 37 | else: 38 | lps[i] = 0 39 | i += 1 40 | 41 | #Now time to test 42 | txt = "abdefgh" 43 | pat = "defg" 44 | KMPSearch(pat,txt) 45 | -------------------------------------------------------------------------------- /String/Length-of-last-word.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. 3 | 4 | If the last word does not exist, return 0. 5 | 6 | Note: A word is defined as a character sequence consists of non-space characters only. 7 | ''' 8 | def check(s): 9 | s = s.rstrip(' ') 10 | s = s.lstrip(' ') 11 | for i in range(len(s)-1,-1,-1): 12 | if s[i] == ' ': 13 | return len(s) - i -1 14 | return len(s) 15 | 16 | s = " xDGBklKecz IAcOJYOH O WY WPi" 17 | c = 0 18 | print check(s) 19 | -------------------------------------------------------------------------------- /String/Longest-Common-Prefix.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Write a function to find the longest common prefix string amongst an array of strings. 3 | 4 | Longest common prefix for a pair of strings S1 and S2 is the longest string S which is the prefix of both S1 and S2. 5 | 6 | As an example, longest common prefix of "abcdefgh" and "abcefgh" is "abc". 7 | 8 | Given the array of strings, you need to find the longest S which is the prefix of ALL the strings in the array. 9 | ''' 10 | def checkPrefix(prefix,st): 11 | j = 0 12 | len_ = 0 13 | for i in range(len(prefix)): 14 | if st[i] != prefix[j]: 15 | break 16 | j += 1 17 | len_ +=1 18 | return prefix[0:len_] 19 | 20 | def LCP(arr): 21 | min_ = len(arr[0]) 22 | index = 0 23 | for i in range(1,len(arr)): 24 | m = len(arr[i]) 25 | if m < min_: 26 | min_ = m 27 | index = i 28 | prefix = arr[index] 29 | for i in arr: 30 | prefix = checkPrefix(prefix,i) 31 | 32 | return prefix 33 | 34 | arr = [ "aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ] 35 | print LCP(arr) 36 | 37 | 38 | 39 | 40 | 41 | 42 | #Divide and Conquer Approach 43 | def commonPrefix(st1,st2): 44 | j = 0 45 | len = 0 46 | for i in range(min(len(st1),lem(st2))): 47 | if st1[i] != st2[j]: 48 | break 49 | else: 50 | j += 1 51 | len += 1 52 | return st1[0:len] 53 | 54 | 55 | def LongestCommonPrefix(arr): 56 | low = 0 57 | high = len(arr) 58 | if low == high: 59 | return arr[low] 60 | if low < high: 61 | mid = (high - low)/2 62 | st1 = LongestCommonPrefix(arr,low,mid) 63 | st2 = LongestCommonPrefix(arr,mid+1,high) 64 | 65 | return commonPrefix(st1,st2) 66 | -------------------------------------------------------------------------------- /String/Longest-Palindrome-substring.py: -------------------------------------------------------------------------------- 1 | 2 | # This function prints the longest palindrome 3 | # substring of st[]. It also returns the length 4 | # of the longest palindrome 5 | def longestPalSubstr(st) : 6 | n = len(st) 7 | table = [[0 for x in range(n)] for y in range(n)] 8 | 9 | maxLength = 1 10 | i = 0 11 | while (i < n) : 12 | table[i][i] = True 13 | i = i + 1 14 | 15 | # check for sub-string of length 2. 16 | start = 0 17 | i = 0 18 | while i < n - 1 : 19 | if (st[i] == st[i + 1]) : 20 | table[i][i + 1] = True 21 | start = i 22 | maxLength = 2 23 | i = i + 1 24 | 25 | # Check for lengths greater than 2. 26 | # k is length of substring 27 | k = 3 28 | while k <= n : 29 | # Fix the starting index 30 | i = 0 31 | while i < (n - k + 1) : 32 | 33 | # Get the ending index of 34 | # substring from starting 35 | # index i and length k 36 | j = i + k - 1 37 | 38 | # checking for sub-string from 39 | # ith index to jth index iff 40 | # st[i+1] to st[(j-1)] is a 41 | # palindrome 42 | if (table[i + 1][j - 1] and 43 | st[i] == st[j]) : 44 | table[i][j] = True 45 | 46 | if (k > maxLength) : 47 | start = i 48 | maxLength = k 49 | i = i + 1 50 | k = k + 1 51 | 52 | return st[start:start + maxLength - 1] # return length of LPS 53 | 54 | st = "aaaabaaa" 55 | print longestPalSubstr(st) 56 | -------------------------------------------------------------------------------- /String/Palindrome-String.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. 3 | 4 | Example: 5 | 6 | "A man, a plan, a canal: Panama" is a palindrome. 7 | 8 | "race a car" is not a palindrome. 9 | 10 | Return 0 / 1 ( 0 for false, 1 for true ) for this problem 11 | ''' 12 | class Solution: 13 | # @param A : string 14 | # @return an integer 15 | def isPalindrome(self, A): 16 | i = 0 17 | j = len(A)-1 18 | while True: 19 | if i>j: break 20 | if not A[i].isalpha() and not A[i].isdigit(): 21 | i+=1 22 | continue 23 | if not A[j].isalpha() and not A[j].isdigit(): 24 | j-=1 25 | continue 26 | if not A[i].lower() == A[j].lower(): 27 | return 0 28 | i+=1 29 | j-=1 30 | return 1 31 | -------------------------------------------------------------------------------- /String/Power-of-2.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Find if Given number is power of 2 or not. 3 | More specifically, find if given number can be expressed as 2^k where k >= 1. 4 | ''' 5 | class Solution: 6 | # @param A : string 7 | # @return an integer 8 | def power(self, num): 9 | num = int(num) 10 | if num == 1: 11 | return 0 12 | while num != 1: 13 | if num%2 != 0: 14 | return 0 15 | num = num/2 16 | return 1 17 | -------------------------------------------------------------------------------- /String/Reverse-Strings.py: -------------------------------------------------------------------------------- 1 | '''Given an input string, reverse the string word by word.''' 2 | class Solution: 3 | # @param A : string 4 | # @return string 5 | def reverseWords(self, a): 6 | 7 | s = a.split() 8 | s.reverse() 9 | res = " ".join(s) 10 | return res 11 | -------------------------------------------------------------------------------- /String/Roman-To-Integer.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given a roman numeral, convert it to an integer. 3 | 4 | Input is guaranteed to be within the range from 1 to 3999. 5 | ''' 6 | def value(num): 7 | if num == 'X': 8 | return 10 9 | if num == 'I': 10 | return 1 11 | if num == 'V': 12 | return 5 13 | if num == 'L': 14 | return 50 15 | if num == 'C': 16 | return 100 17 | if num == 'D': 18 | return 500 19 | if num == 'M': 20 | return 1000 21 | 22 | def romanToInteger(roman): 23 | res = 0 24 | i = 0 25 | while i < len(roman): 26 | value1 = value(roman[i]) 27 | if i+1 < len(roman): 28 | value2 = value(roman[i+1]) 29 | if value1 >= value2: 30 | res += value1 31 | i += 1 32 | else: 33 | res += value2 - value1 34 | i += 2 35 | else: 36 | res = res + value1 37 | i += 1 38 | return res 39 | roman = "XXXIV" 40 | print romanToInteger(roman) 41 | -------------------------------------------------------------------------------- /String/Searching-word-in-2D-matrix.py: -------------------------------------------------------------------------------- 1 | def findword(matrix,row,col,word): 2 | x = [-1,-1,-1,0,0,1,1,1] 3 | y = [-1,0,1,-1,1,-1,0,1] 4 | #if first vhar of word doesn't match with given starting point in grid 5 | if matrix[row][col] != word[0]: 6 | return False 7 | len_ = len(word) 8 | #searching words in all directions 9 | for dir_ in range(8): 10 | #intialize starting point for curr direction 11 | rd = row + x[dir_] 12 | cd = col + y[dir_] 13 | #first character is already matched,check remaining char 14 | for k in range(1,len_): 15 | if rd >= len(matrix) or rd <0 or cd >= len(matrix[0]) or cd < 0: 16 | break 17 | #if not matched break 18 | if matrix[rd][cd] != word[k]: 19 | break 20 | rd += x[dir_] 21 | cd += y[dir_] 22 | if k == len_: 23 | return True 24 | return False 25 | 26 | def patternSearch(matrix,word): 27 | for row in range(len(matrix)): 28 | for col in range(len(matrix[0])): 29 | if findword(matrix,row,col,word): 30 | return row,col 31 | 32 | matrix = [['G','E','E','K','S','F'],['Q','U','I','Z','Q','A'],['A','B','C','D','E','F']] 33 | print patternSearch(matrix,"GEEKS") 34 | -------------------------------------------------------------------------------- /String/Valid-Number.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Validate if a given string is numeric. 3 | 4 | Examples: 5 | 6 | "0" => true 7 | " 0.1 " => true 8 | "abc" => false 9 | "1 a" => false 10 | "2e10" => true 11 | Return 0 / 1 ( 0 for false, 1 for true ) for this problem 12 | ''' 13 | class Solution: 14 | # @param A : string 15 | # @return an integer 16 | def isNumber(self, A): 17 | A = A.strip() 18 | n = len(A) 19 | if n == 0: 20 | return 0 21 | if A[0] == '+' or A[0] == '-': 22 | A = A[1:] 23 | n = n - 1 24 | if n == 0: 25 | return 0 26 | i = 0 27 | dotEncountered = False 28 | eEncountered = False 29 | while i < n: 30 | if A[i] >= '0' and A[i] <= '9': 31 | i += 1 32 | continue 33 | if A[i] == '.': 34 | if dotEncountered: 35 | return 0 36 | dotEncountered = True 37 | i += 1 38 | if i >= n: 39 | return 0 40 | elif A[i] == 'e': 41 | return 0 42 | elif A[i] == 'e': 43 | if eEncountered: 44 | return 0 45 | eEncountered = True 46 | dotEncountered = True 47 | i += 1 48 | if i < n and (A[i] == '-' or A[i] == '+'): 49 | i += 1 50 | else: 51 | return 0 52 | return 1 53 | -------------------------------------------------------------------------------- /String/Valid-ip-address.py: -------------------------------------------------------------------------------- 1 | '''Given a string containing only digits, restore it by returning all possible valid IP address combinations. 2 | 3 | A valid IP address must be in the form of A.B.C.D, where A,B,C and D are numbers from 0-255. The numbers cannot be 0 prefixed unless they are 0. 4 | 5 | Example: 6 | 7 | Given “25525511135”, 8 | 9 | return [“255.255.11.135”, “255.255.111.35”]. (Make sure the returned strings are sorted in order)''' 10 | def validIpAddress(st): 11 | temp = [] 12 | def is_valid(x): 13 | return x and int(x) < 256 and not (s.startwith('0') and len(x) > 1) 14 | for i in range(1,4): 15 | if not is_valid(st[:i]): 16 | continue 17 | for j in range(i,i+4): 18 | if not is_valid(st[i:j]): 19 | continue 20 | for l in range(j,j+4): 21 | if not (is_valid(st[j:l]) and is_valid(st[l:])): 22 | continue 23 | ip = st[:i], st[i:j], st[j:l], st[l:] 24 | temp.append('.'.join(ip)) 25 | return sorted(temp) 26 | -------------------------------------------------------------------------------- /String/addBinaryString.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given two binary strings, return their sum (also a binary string). 3 | ''' 4 | def binarySum(a,b): 5 | n1 = len(a) 6 | n2 = len(b) 7 | if n1 > n2: 8 | b = "0"*(n1-n2) + b 9 | elif n2 > n1: 10 | a = "0"*(n2-n1) + a 11 | carry = 0 12 | a = list(a) 13 | b = list(b) 14 | for i in range(n2-1,-1,-1): 15 | if (a[i] == b[i]) and a[i] == '0': 16 | a[i] = str(0+carry) 17 | carry = 0 18 | elif (a[i] == b[i]) and a[i] == '1': 19 | a[i] = str(0 + carry) 20 | carry = 1 21 | else: 22 | if carry == 1: 23 | a[i] = str(0) 24 | carry = 1 25 | else: 26 | a[i] = str(1) 27 | carry = 0 28 | if carry == 1: 29 | a = ["1"] + a 30 | 31 | return ''.join(a) 32 | 33 | a = "1110000000010110111010100100111" 34 | b = "101001" 35 | 36 | print binarySum(a,b) 37 | 38 | 39 | ''' 40 | Another Approach 41 | ''' 42 | def add(a,b): 43 | a = int(a,2) 44 | b = int(b,2) 45 | c = bin(a+b)[2:] 46 | return c 47 | -------------------------------------------------------------------------------- /String/compare-version-numbers.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Compare two version numbers version1 and version2. 3 | 4 | If version1 > version2 return 1, 5 | If version1 < version2 return -1, 6 | otherwise return 0. 7 | You may assume that the version strings are non-empty and contain only digits and the . character. 8 | The . character does not represent a decimal point and is used to separate number sequences. 9 | For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. 10 | 11 | Here is an example of version numbers ordering: 12 | 13 | 0.1 < 1.1 < 1.2 < 1.13 < 1.13.4 14 | ''' 15 | class Solution: 16 | # @param A : string 17 | # @param B : string 18 | # @return an integer 19 | def compareVersion(self, version1, version2): 20 | v1, v2 = (map(int, v.split('.')) for v in (version1, version2)) 21 | d = len(v2) - len(v1) 22 | return cmp(v1 + [0]*d, v2 + [0]*-d) 23 | 24 | 25 | ''' 26 | Without inbuilt function Approach 27 | ''' 28 | def compare(v1,v2): 29 | v1 = v1.split('.') 30 | v2 = v2.split('.') 31 | while v1 !=[] and int(v1[-1] == 0): 32 | v1.pop() 33 | while v2 != [] and int(v2[-1] == 0): 34 | v2.pop() 35 | m = min(len(v1,v2)) 36 | for i in range(m): 37 | a = v1[i] 38 | b = v2[i] 39 | if a > b: 40 | return 1 41 | elif a < b: 42 | return -1 43 | if len(v1) > len(v2): 44 | return 1 45 | if len(v1) == len(v2): 46 | return 0 47 | return -1 48 | -------------------------------------------------------------------------------- /String/minimum-characters-required-to-make-a-string-palindrome.py: -------------------------------------------------------------------------------- 1 | ''' 2 | You are given a string. The only operation allowed is to insert characters in the beginning of the string. How many minimum characters are needed to be inserted to make the string a palindrome string 3 | 4 | Example: 5 | Input: ABC 6 | Output: 2 7 | Input: AACECAAAA 8 | Output: 2 9 | ''' 10 | def computeLPSArray(pat): 11 | j = 0 12 | i = 1 13 | m = len(pat) 14 | lps = [0]*m 15 | lps[0] = 0 16 | while i < m: 17 | 18 | if pat[i] == pat[j]: 19 | j += 1 20 | lps[i] = j 21 | i += 1 22 | else: 23 | if j != 0 and pat[i] != pat[j]: 24 | j = lps[j - 1] 25 | else: 26 | lps[i] = 0 27 | i += 1 28 | return lps 29 | 30 | st = "ABC" 31 | rev = st + "$" + st[::-1] 32 | lps = computeLPSArray(rev) 33 | print len(st) - lps[len(lps)-1] 34 | -------------------------------------------------------------------------------- /Tree/BST-Insertion.py: -------------------------------------------------------------------------------- 1 | def insert(root,node): 2 | if root is None: 3 | root = node 4 | 5 | else: 6 | if root.valkey: 5 | return binarySearchTree(root.left,key) 6 | else: 7 | return binarySearchTree(root.right,key) 8 | -------------------------------------------------------------------------------- /Tree/Print-Binary-Tree-in-Vertical-order.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,data): 3 | self.key =data 4 | self.left = None 5 | delf.right = None 6 | 7 | def getVerticalOrder(root,hd,m): 8 | if root is None: 9 | return 10 | 11 | try: 12 | m[hd].append(root.key) 13 | except: 14 | m[hd] = [root.key] 15 | 16 | #Stores nodes in left subtree 17 | getVerticalOrder(root.left,hd-1,m) 18 | #Stores nodes in right subtree 19 | getVerticalOrder(root.right,hd+1,m) 20 | 21 | def printVerticalOrder(root): 22 | m = dict() 23 | hd = 0 24 | getVerticalOrder(root,hd,m) 25 | 26 | for index,value in enumerate(sorted(m)): 27 | for i in m[value]: 28 | print i, 29 | print 30 | 31 | root = Node(1) 32 | root.left = Node(2) 33 | root.right = Node(3) 34 | root.left.left = Node(4) 35 | root.left.right = Node(5) 36 | root.right.left = Node(6) 37 | root.right.right = Node(7) 38 | root.right.left.right = Node(8) 39 | root.right.right.right = Node(9) 40 | print "Vertical order traversal is" 41 | printVerticalOrder(root) 42 | -------------------------------------------------------------------------------- /Tree/Tree-Traversal.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,key): 3 | self.val = key 4 | self.left = None 5 | self.right = None 6 | 7 | def printInorder(root): 8 | if root: 9 | 10 | #Recur on left child 11 | printInorder(root.left) 12 | #Print Root data 13 | print (root.val), 14 | #Recur on right child 15 | printInorder(root.right) 16 | 17 | def printPostorder(root): 18 | if root: 19 | #First Recur on left child 20 | printPostorder(root.left) 21 | 22 | printPostorder(root.right) 23 | 24 | print (root.val), 25 | 26 | def printPreorder(root): 27 | if root: 28 | print root.val, 29 | printPreorder(root.left) 30 | printPreorder(root.right) 31 | 32 | # Driver code 33 | root = Node(1) 34 | root.left = Node(2) 35 | root.right = Node(3) 36 | root.left.left = Node(4) 37 | root.left.right = Node(5) 38 | print "Preorder traversal of binary tree is" 39 | printPreorder(root) 40 | 41 | print "\nInorder traversal of binary tree is" 42 | printInorder(root) 43 | 44 | print "\nPostorder traversal of binary tree is" 45 | printPostorder(root) 46 | -------------------------------------------------------------------------------- /Tree/ZigzagLevelOrderTraversal.py: -------------------------------------------------------------------------------- 1 | def zizZagLevelOrder(root): 2 | if not root: 3 | return [] 4 | res = [] 5 | temp = [] 6 | stack = [root] 7 | flag = 1 8 | while stack: 9 | for i in range(len(stack)): 10 | node = stack.pop(0) 11 | temp += [node.val] 12 | if node.left: 13 | stack += [node.left] 14 | if node.right: 15 | stack += [node.right] 16 | res += [temp[::flag]] 17 | temp = [] 18 | flag *= -1 19 | return res 20 | 21 | print zizZagLevelOrder([3, 9, 20, None, None, 15, 7]) 22 | -------------------------------------------------------------------------------- /Tree/balanced-binary-tree.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isBalanced(self,root): 3 | def check(root): 4 | if root is None: 5 | return 0 6 | left = check(root.left) 7 | right = check(root.right) 8 | if left == -1 or right == -1 or abs(left - right) > 1: 9 | return -1 10 | return 1 + max(left,right) 11 | return check(root) != -1 12 | -------------------------------------------------------------------------------- /Tree/inOrderTraversal.py: -------------------------------------------------------------------------------- 1 | def inOrder(root): 2 | curr = root 3 | s = [] 4 | done = 0 5 | ans = [] 6 | while (not done): 7 | if curr is not None: 8 | s.append(curr) 9 | curr = curr.left 10 | else: 11 | if len(s) > 0: 12 | curr = s.pop() 13 | ans.append(curr.data) 14 | curr = curr.right 15 | else: 16 | done = 1 17 | -------------------------------------------------------------------------------- /Tree/level-order-traversal.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self,key): 3 | self.val = key 4 | self.left = None 5 | self.right = None 6 | 7 | def printLevelOrder(root): 8 | h = height(root) 9 | for i in range(1,h+1): 10 | printGivenOrder(root,i) 11 | 12 | def printGivenOrder(root,level): 13 | if root is None: 14 | return 15 | if level == 1: 16 | print "%d" %(root.val), 17 | elif level >1: 18 | printGivenOrder(root.left,level-1) 19 | printGivenOrder(root.right,level-1) 20 | 21 | def height(node): 22 | if node is None: 23 | return 0 24 | else: 25 | #Compute Height of each subtree 26 | lheight = height(node.left) 27 | rheight = height(node.right) 28 | 29 | if lheight>rheight: 30 | return lheight+1 31 | else: 32 | return rheight+1 33 | 34 | 35 | # Driver program to test above function 36 | root = Node(1) 37 | root.left = Node(2) 38 | root.right = Node(3) 39 | root.left.left = Node(4) 40 | root.left.right = Node(5) 41 | 42 | print "Level order traversal of binary tree is -" 43 | printLevelOrder(root) 44 | -------------------------------------------------------------------------------- /Two Pointers/3Sum.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. 4 | Return the sum of the three integers. 5 | 6 | Assume that there will only be one solution 7 | 8 | Example: 9 | given array S = {-1 2 1 -4}, 10 | and target = 1. 11 | 12 | The sum that is closest to the target is 2. (-1 + 2 + 1 = 2) 13 | ''' 14 | def closestSum(arr,target): 15 | i = 0 16 | arr = sorted(arr) 17 | min_ = float('inf') 18 | n = len(arr) 19 | res= 0 20 | while (i < n): 21 | j = i+1 22 | k = n-1 23 | while (j arr[k]): 24 | k += 1 25 | count += k - j - 1 26 | return count%(10**9 + 7) 27 | -------------------------------------------------------------------------------- /Two Pointers/Intersection-of arrays.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Find the intersection of two sorted arrays. 3 | OR in other words, 4 | Given 2 sorted arrays, find all the elements which occur in both the arrays. 5 | ''' 6 | class Solution: 7 | # @param A : tuple of integers 8 | # @param B : tuple of integers 9 | # @return a list of integers 10 | def intersect(self, a, b): 11 | i =0 12 | j = 0 13 | lis = [] 14 | if a == b: 15 | return a 16 | while i < len(a) and j < len(b): 17 | if a[i] > b[j]: 18 | j += 1 19 | elif a[i] < b[j]: 20 | i += 1 21 | elif a[i] == b[j]: 22 | lis.append(a[i]) 23 | i +=1 24 | j += 1 25 | return lis 26 | -------------------------------------------------------------------------------- /Two Pointers/Intersection.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Find the intersection of two sorted arrays. 3 | OR in other words, 4 | Given 2 sorted arrays, find all the elements which occur in both the arrays. 5 | ''' 6 | def intersection(a,b): 7 | i =0 8 | j = 0 9 | lis = [] 10 | if a == b: 11 | return a 12 | while i < len(a) and j < len(b): 13 | if a[i] > b[j]: 14 | j += 1 15 | elif a[i] < b[j]: 16 | i += 1 17 | elif a[i] == b[j]: 18 | lis.append(a[i]) 19 | i +=1 20 | j += 1 21 | return lis 22 | 23 | a = [1,2,3,3,4,5,6] 24 | b = [3,3,5] 25 | print intersection(a,b) 26 | -------------------------------------------------------------------------------- /Two Pointers/Maxseries1s.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A : list of integers 3 | # @param B : integer 4 | # @return a list of integers 5 | def maxone(self, arr, m): 6 | wl ,wr =0, 0 7 | bestl, bestWin = 0, 0 8 | zeroCount = 0 9 | n = len(arr) 10 | lis = [] 11 | while wr < n: 12 | if zeroCount <= m: 13 | if arr[wr] == 0: 14 | zeroCount += 1 15 | wr += 1 16 | if zeroCount > m: 17 | if arr[wl] == 0: 18 | zeroCount -= 1 19 | wl += 1 20 | if (wr - wl > bestWin): 21 | bestWin = wr - wl 22 | bestl = wl 23 | for i in range(bestWin): 24 | lis.append(bestl+i) 25 | return lis 26 | -------------------------------------------------------------------------------- /Two Pointers/Merge-Two-Sorted-Lists.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given two sorted integer arrays A and B, merge B into A as one sorted array. 3 | 4 | Note: You have to modify the array A to contain the merge of A and B. Do not output anything in your code. 5 | TIP: C users, please malloc the result into a new array and return the result. 6 | If the number of elements initialized in A and B are m and n respectively, the resulting size of array A after your code is executed should be m + n 7 | 8 | Example : 9 | 10 | Input : 11 | A : [1 5 8] 12 | B : [6 9] 13 | 14 | Modified A : [1 5 6 8 9]''' 15 | def merge(arr1,arr2): 16 | i = 0 17 | j = 0 18 | lis = [] 19 | n1 = len(arr1) 20 | n2 = len(arr2) 21 | if n1 == 0: 22 | return arr2 23 | if n2 == 0: 24 | return arr1 25 | while i < n1 and j < n2: 26 | if arr1[i] > arr2[j]: 27 | lis.append(arr2[j]) 28 | j += 1 29 | elif arr1[i] < arr2[j]: 30 | lis.append(arr1[i]) 31 | i += 1 32 | else: 33 | lis.append(arr1[i]) 34 | i += 1 35 | while i < n1: 36 | lis.append(arr1[i]) 37 | i += 1 38 | while j < n2: 39 | lis.append(arr2[j]) 40 | j += 1 41 | return lis 42 | arr1 = [1,2] 43 | arr2 = [-1,2] 44 | print merge(arr1,arr2) 45 | -------------------------------------------------------------------------------- /Two Pointers/MinAbsDiff.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given three sorted arrays A, B and Cof not necessarily same sizes. 3 | 4 | Calculate the minimum absolute difference between the maximum and minimum number from the triplet a, b, c such that a, b, c belongs arrays A, B, C respectively. 5 | i.e. minimize | max(a,b,c) - min(a,b,c) |. 6 | 7 | Example : 8 | 9 | Input: 10 | 11 | A : [ 1, 4, 5, 8, 10 ] 12 | B : [ 6, 9, 15 ] 13 | C : [ 2, 3, 6, 6 ] 14 | Output: 15 | 16 | 1 17 | Explanation: We get the minimum difference for a=5, b=6, c=6 as | max(a,b,c) - min(a,b,c) | = |6-5| = 1 18 | ''' 19 | def minimize(a,b,c): 20 | i, j, k = 0, 0, 0 21 | diff = float('inf') 22 | res_i, res_j, res_k = 0, 0, 0 23 | while i arr[i-2]: 19 | arr[i] = n 20 | i += 1 21 | return i 22 | arr = [1,1,1,2 ] 23 | print check(arr) 24 | -------------------------------------------------------------------------------- /Two Pointers/RemoveDuplicates.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Remove duplicates from Sorted Array 3 | Given a sorted array, remove the duplicates in place such that each element appears only once and return the new length. 4 | 5 | Note that even though we want you to return the new length, make sure to change the original array as well in place 6 | 7 | Do not allocate extra space for another array, you must do this in place with constant memory.''' 8 | class Solution: 9 | # @param A : list of integers 10 | # @return an integer 11 | def removeDuplicates(self, arr): 12 | n = len(arr) 13 | if n == 0 or n == 1: 14 | return n 15 | j = 0 16 | for i in range(n-1): 17 | if arr[i] != arr[i+1]: 18 | arr[j] = arr[i] 19 | j += 1 20 | arr[j] = arr[n-1] 21 | return j+1 22 | -------------------------------------------------------------------------------- /Two Pointers/RemoveElements.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Given an array and a value, remove all the instances of that value in the array. 3 | Also return the number of elements left in the array after the operation. 4 | It does not matter what is left beyond the expected length. 5 | 6 | Example: 7 | If array A is [4, 1, 1, 2, 1, 3] 8 | and value elem is 1, 9 | then new length is 3, and A is now [4, 2, 3] 10 | Try to do it in less than linear additional space complexity. 11 | ''' 12 | def removeElement(arr,target): 13 | i = 0 14 | j = 0 15 | n = len(arr) 16 | while i < n: 17 | if arr[i] != target: 18 | arr[j] = arr[i] 19 | j += 1 20 | 21 | i += 1 22 | return len(arr[0:j]) 23 | 24 | arr = [4,1,1,2,1,3] 25 | target = 1 26 | print removeElement(arr,target) 27 | -------------------------------------------------------------------------------- /Two Pointers/array-3-pointers.py: -------------------------------------------------------------------------------- 1 | ''' 2 | You are given 3 arrays A, B and C. All 3 of the arrays are sorted. 3 | 4 | Find i, j, k such that : 5 | max(abs(A[i] - B[j]), abs(B[j] - C[k]), abs(C[k] - A[i])) is minimized. 6 | Return the minimum max(abs(A[i] - B[j]), abs(B[j] - C[k]), abs(C[k] - A[i])) 7 | 8 | **abs(x) is absolute value of x and is implemented in the following manner : ** 9 | 10 | if (x < 0) return -x; 11 | else return x; 12 | Example : 13 | 14 | Input : 15 | A : [1, 4, 10] 16 | B : [2, 15, 20] 17 | C : [10, 12] 18 | 19 | Output : 5 20 | With 10 from A, 15 from B and 10 from C. 21 | ''' 22 | def minimize(a,b,c): 23 | i, j, k = 0, 0, 0 24 | diff = float('inf') 25 | res_i, res_j, res_k = 0, 0, 0 26 | while i