Problem: Implement an algorithm to determine if a string has all unique characters. What if you cannot use additional data structures?
def isUniqueChars(str):
#first sort the string O(nlgn)
sortedStr = "".join(sorted(str))
isUnique = True
#compare the consecutive characters O(n)
for i in range(len(sortedStr)-1):
if sortedStr[i] == sortedStr[i+1]:
isUnique = False
return isUnique
print isUniqueChars("Amber".lower())
print isUniqueChars("madam".lower())
def isUniqueChars2(str):
#considering the characters are ascii characters building an array for 256 characters acting as a hash table
arr = [0]*256
for c in str:
asciiValue = ord(c)
arr[asciiValue] += 1
isUnique = True
#checking for repeated characters O(1)
for entries in str:
if arr[ord(entries)] > 1:
isUnique = False
return isUnique
print isUniqueChars2("Amber".lower())
print isUniqueChars2("madam".lower())
Hi! If you are thinking where have you arrived and have no clue of whats going on then visit this page.
Here is the lecture on stacks by Prof Naveen Garg.
A very simple implementation of a Stack in Python is explained below.
#class for defining a stack
class Stack:
def __init__(self):
self.items = []
#method for pushing an item on a stack
def push(self,item):
self.items.append(item)
#method for popping an item from a stack
def pop(self):
return self.items.pop()
#method to check whether the stack is empty or not
def isEmpty(self):
return (self.items == [])
#method to get the top of the stack
def topOfStack(self):
return len(self.items)
def __str__(self):
return str(self.items)
if __name__ == "__main__":
stck = Stack()
stck.push(5)
stck.push(10)
stck.push(15)
stck.push(20)
print stck
#Output = [5, 10, 15, 20]
stck.pop()
print stck
#Output = [5, 10, 15]
print stck.topOfStack()
#Output = 3
We will learn about how to implement stacks using Linked Lists later, when we cover Linked Lists. At this moment we will use the stack created above for solving most of the problems related to Stacks.
1. Write a code for showing how stacks can be used for checking balancing of symbols.
Soln: The algorithm is as follows:
Step 1. Create a stack.
Step 2. Scan the input and while the end is not reached perform the following steps:
Step 2a. If the character read is not a symbol to be balanced then ignore it.
Step 2b. If the character is an opening symbol like “(,{ or [” then push it onto the stack.
Step 2c. If the character is a closing symbol like “), } or ]” then if the stack is empty then return that the given input is unbalanced, else pop the symbol from the top of the stack.
Step 2d. If the symbol popped is not the corresponding opening symbol of the closing symbol currently being scanned then return that the given input is unbalanced.
The Python program implementing the problem is as follows:
class Stack:
def __init__(self):
self.items = []
#method for pushing an item on a stack
def push(self,item):
self.items.append(item)
#method for popping an item from a stack
def pop(self):
return self.items.pop()
#method to check whether the stack is empty or not
def isEmpty(self):
return (self.items == [])
#method to get the top of the stack
def topOfStack(self):
return len(self.items)
def __str__(self):
return str(self.items)
def matches(top,symbol):
openingSymbols = "({["
closingSymbols = ")}]"
return openingSymbols.index(top) == closingSymbols.index(symbol)
def checkBalance(input):
symbolstack = Stack()
balanced = False
for symbols in input:
if symbols in ["(","{","["]:
symbolstack.push(symbols)
else:
if symbolstack.isEmpty():
balanced = False
else:
topSymbol = symbolstack.pop()
if not matches(topSymbol,symbols):
balanced = False
else:
balanced = True
return balanced
print checkBalance("([)]")
'''Output: False'''
print checkBalance("{{([][])}()}")
'''Output: True'''
2. Convert a decimal number into the number of a particular given base.
class Stack:
def __init__(self):
self.items = []
#method for pushing an item on a stack
def push(self,item):
self.items.append(item)
#method for popping an item from a stack
def pop(self):
return self.items.pop()
#method to check whether the stack is empty or not
def isEmpty(self):
return (self.items == [])
#method to get the top of the stack
def topOfStack(self):
return len(self.items)
def __str__(self):
return str(self.items)
def baseConversion(decimalNum,base):
digits = "0123456789ABCDEF"
remainderStack = Stack()
while (decimalNum > 0):
remainderStack.push(decimalNum % base)
decimalNum //= base
convertedString = ""
while not remainderStack.isEmpty():
convertedString = convertedString + digits[remainderStack.pop()]
return convertedString
print baseConversion(25,2)
'''Output 11001'''
print baseConversion(1000,16)
'''Output 3E8'''
3. Check whether a given string is a palindrome or not?
Sample Input: “madam”
Sample Output: True
Soln:
class Stack:
def __init__(self):
self.items = []
#method for pushing an item on a stack
def push(self,item):
self.items.append(item)
#method for popping an item from a stack
def pop(self):
return self.items.pop()
#method to check whether the stack is empty or not
def isEmpty(self):
return (self.items == [])
#method to get the top of the stack
def topOfStack(self):
return len(self.items)
def __str__(self):
return str(self.items)
def isPalindrome(str):
strStack = Stack()
palindrome = False
for char in str:
strStack.push(char)
for char in str:
if char == strStack.pop():
palindrome = True
else:
palindrome = False
return palindrome
print isPalindrome("madam")
This blog is an effort from my side to be in touch with Data Structures and Algorithms and practice questions that are often asked in coding interviews. People might not find anything very new in this blog, but they will certainly find the topics related to data structures and algorithms organized in a sequential manner, where we start from the basics and explore the concepts to solve various problems. This blog would certainly be helpful for those who are preparing for interviews.
Almost all the codes would be written in Python. This is because thats’ the language I am most comfortable with. I am sorry if you don’t know the language as most people prefer C++ or Java. If you want to learn Python, you can easily do so and it should not take more than a week. Its very close to writing Pseudo Codes. I learnt it for the first time from here. Try it out. Most of the big companies don’t mind what you code in. Infact Google uses python a lot. So does the other companies. Most importantly Python is used by Data Scientists, and Data Science is regarded as the sexiest job of the 21st century. Check out this article by Harvard Business Review: http://hbr.org/2012/10/data-scientist-the-sexiest-job-of-the-21st-century/ar/1. Fortunately, I am also into data science and belong to the same breed of people often known as Data Scientists. I will soon start a new blog that would showcase my works on Data Science.
I am a big fan of IIT (Indian Institute of Technology) and also a big fan of IIT-Delhi. 🙂 I am biased about this as my fiance is a IITD grad. But I genuinely feel that Prof Naveen Gargs’ lectures on Data Structure and Algorithms are very easy to follow and can be a solid foundation for anyone who is interested to learn them. So I would be providing links to his lectures, every time I cover a topic. A full list of his lectures can be found over here.
Regarding the programming problems related to a topic I would like to follow this book (Coding Interview Questions by Narasimha Karumanchi). This book might not be a great book. But surely it has good problems to start with. I totally believe that the problems in this book would help anyone to be clear with the basic data structure and algorithm problems that are asked by interviewers. Trust me on this. I mostly have a good experience with the book.
I have sketched out the topics below. As soon as I start adding materials to the topic, each of them would become clickable and will lead you to the various blog posts related to the topic. Don’t hesitate, just click, read and give suggestions, provide better solutions. After all, I am always open for them.
So lets sketch out the outline of the topics that we will cover:
1. Introduction to Data Structures and Algorithms
2. Stacks
3. Queues and Linked Lists
4. Dictionaries
5. Hashing
6. Trees
7. Tree Walks / Traversals
8. Ordered Dictionaries
9. Deletion
10. Quick Sort
11. AVL Trees
12. AVL Trees
13. Trees
14. Red Black Trees
15. Insertion in Red Black Trees
16. Disk Based Data Structures
17. Case Study: Searching for Patterns
18. Tries
19. Data Compression
20. Priority Queues
21. Binary Heaps
22. Why Sorting
23. More Sorting
24. Graphs
25. Data Structures for Graphs
26. Two Applications of Breadth First Search
27. Depth First Search
28. Applications of DFS
29. DFS in Directed Graphs
30. Applications of DFS in Directed Graphs
31. Minimum Spanning Trees
32. The Union
33. Prims Algorithm for Minimum Spanning Trees
34. Single Source Shortest Paths
35. Correctness of Dijkstras Algorithm
36. Single Source Shortest Paths
Have a look at this video and learn quick sort with Hungarian Folk Dance.
Here is another very good video that illustrates quick sort.
Here are some different ways of implementing quick sort in Python.
import random
from random import randrange
mylist = [3,0,1,8,7,2,5,4,9,6]
def qsort1(mylist):
if mylist == []:
return []
else:
pivot = mylist[0]
lesser = qsort1([x for x in mylist[1:] if x < pivot])
greater = qsort1([x for x in mylist[1:] if x >= pivot])
return lesser + [pivot] + greater
print qsort1(mylist)
def partition(mylist, l, e, g):
while mylist != []:
head = mylist.pop(0)
if head < e[0]:
l = [head] + l
if head > e[0]:
g = [head]+ g
if head == e[0]:
e = [head] + e
return (l,e,g)
def qsort2(mylist):
if mylist == []:
return []
else:
pivot = mylist[0]
lesser,equal,greater = partition(mylist[1:],[],list([pivot]),[])
return qsort2(lesser)+equal+qsort2(greater)
print qsort2(mylist)
This one works for any randomly chosen pivot element.
def qsort1a(list):
def qsort(list):
if list == []:
return []
else:
pivot = list.pop(randrange(len(list)))
lesser = qsort([l for l in list if l < pivot])
greater = qsort([l for l in list if l >= pivot])
return lesser + [pivot] + greater
return qsort(list[:])
print qsort1a(mylist)
Although recursion is a very easy way of traversing through Binary Tree but it can easily cause memory problems. The iterative solution can be handy in such cases. A very good explanation of iterative inorder traversal of Binary Tree can be found in the following video produced by Saurabh.
I have implemented using python.
'''Binary Tree Class and its methods'''
class BinaryTree:
def __init__(self, root):
self.root = root #root node
self.leftChild = None #left child
self.rightChild = None #right child
#set root node
def setRoot(self, root):
self.root = root
#get root node
def getRoot(self):
return self.root
#get left child of a node
def getLeftChild(self):
return self.leftChild
#get right child of a node
def getRightChild(self):
return self.rightChild
#insert a left child of a node
def insertLeftChild(self, newNode):
if self.leftChild == None:
self.leftChild = BinaryTree(newNode)
else:
t = BinaryTree(newNode)
t.leftChild = self.leftChild
self.leftChild = t
#insert a right child of a node
def insertRightChild(self, newNode):
if self.rightChild == None:
self.rightChild = BinaryTree(newNode)
else:
t = BinaryTree(newNode)
t.rightChild = self.rightChild
self.rightChild = t
#recursive function for inorder traversal of binary tree
def inOrderTraversalRecursive(tree):
if tree == None:
return
else:
inOrderTraversal(tree.leftChild)
print tree.root
inOrderTraversal(tree.rightChild
#iterative function for inorder traversal of binary tree
def inOrderTraversalIterative(tree)
current = tree
stack = []
done = True
while(done):
if current:
stack.append(current)
current = current.getLeftChild()
else:
if stack == []:
done = True
else:
current = stack.pop()
print current.root
current = current.getRightChild()
if __name__ == "__main__":
r = BinaryTree(5)
r.insertLeftChild(6)
r.insertRightChild(7)
r.leftChild.insertLeftChild(12)
r.leftChild.insertRightChild(54)
r.rightChild.insertRightChild(63)
print "Inorder traversal of tree recursively is:", inOrderTraversalRecursive(r)
print "\n\n"
print "Inorder traversal of the tree iteratively is:", inOrderTraversalIterative(r)
print "\n\n"
The problem is as follows:
Given an array of positive integers, all numbers occur even number of times except one number
which occurs odd number of times. Find the number in O(n) time and constant space
Sample Input: [1,2,3,2,3,1,3]
Sample Output: 3
arr = [1,2,3,2,3,1,3]
def detectingOddNumberOccurrence(arr):
number = 0
for i in range(len(arr)):
number ^= arr[i]
return number
print detectingOddNumberOccurrence(arr)
The main funda behind this solution is that if any number is XORed with itself it returns 0. So a number which occurs odd number of times will not give resultant as 0 and would give the number instead.