Dec
07

Binary Search Trees

Tree’s are one of the many fundamental data structures in Computer Science. Today we’ll be talking about a specific kind of tree called the binary search tree. But before I get into that, let me go over what a Binary Tree is first.

A Binary Tree is a data structure composed of nodes that have at most 2 children. A node is a point on the tree that generally has a value associated with it, though it does not have to. As an example, we’ll look at a binary tree composed of integer nodes.

In the above picture we have a binary tree with seven different nodes. The root node (top of the tree) is the node with the value of 7. The left child of 7 is 8 and the right child of 7 is 9. This relationship follows throughout the whole tree. So now that you’ve seen a binary tree lets look at what makes a binary search tree different.

A binary search tree is a special form of binary tree where starting from the root node, you can travel down the tree and the nodes you travel across must follow the following rules. The left child of any node must be less than or equal to the parent node. The right child of any node must be greater than their parent node. In this case, when we build the tree, it will look different depending on the order we insert the nodes. So lets build the previous tree inserting the nodes in the order of 7, 6, 2, 8, 12, 9, 10. We get…

Any x you see is a child node with a null value. The reason binary search trees are useful is that you can search for any node you want and be guaranteed to find it in O(logn) time, assuming that the tree we build ends up being mostly balanced.  There are ways to guarantee that the tree is built in a balanced way but I won’t get into that right now.  As a bonus I will provide some sample code that implements a binary search tree in java below.

public class BST {
	private Node root;
	
	public BST() {
		this.root = null;
	}
	
	public Node getRoot() {
		return this.root;
	}
	
	public void add(int value) {
		if(root == null)
			root = new Node(value);
		else
			insert(value, root);
	}
	
	private void insert(int value, Node n) {
		if(value <= n.getValue()) {
			if(n.getLeft() == null)
				n.setLeft(new Node(value));
			else
				insert(value, n.getLeft());
		} else {
			if(n.getRight() == null)
				n.setRight(new Node(value));
			else
				insert(value, n.getRight());
		}
	}
	
	public boolean find(int value) {
		Node n = this.root;
		while(n != null) {
			if(value < n.getValue())
				n = n.getLeft();
			else if(value == n.getValue())
				return true;
			else
				n = n.getRight();
		}
		return false;
		
	}
	
	

}

public class Node {
	private int value;
	private Node left;
	private Node right;
	
	public Node(int value) {
		this.value = value;
		this.left = null;
		this.right = null;
	}
	
	public Node getLeft() {
		return this.left;
	}
	
	public Node getRight() {
		return this.right;
	}
	
	public int getValue() {
		return this.value;
	}
	
	public void setLeft(Node left) {
		this.left = left;
	}
	
	public void setRight(Node right) {
		this.right = right;
	}
}

Nov
22

Merge Sort

So today I thought I would review the sorting algorithm, merge sort. The idea is that, if you have an unsorted array of integers, you can sort the integers in O(nlogn) time using merge sort. To implement this, we need to split the sorting algorithm into smaller tasks. A great way to do this is by using recursion. As an example, lets say we have an array with the integers 7, 5, 2, 4, 9 , 1, 12, 3, in that order. To break this up, lets split the array in half.

So now we have 7, 5, 2, 4          and          9, 1, 12, 3

We can split these in half to get…

7, 5          2, 4          9, 1          12, 3

This is good enough to work with, in reality, the implemented algorithm will actually split these numbers all the way down to just the individual numbers with no pairs, but for analyzation purposes and understanding merge sort, we won’t worry about this for now. The next step will be to sort the pairs.

So we’ll compare 7 and 5 and notice that 7 > 5 so we switch the two. For 2, 4 we find that these are already sorted. We’ll also need to switch 9, 1 and 12, 3. So now we have the following pairs.

5, 7          2, 4          1, 9          3, 12

Now, we’ll combine the 5, 7 pair with the 2, 4. First we compare 5 and 2. Since 2 is smaller the 2 will now go where the 5 is, to determine the next number we’ll compare 5 and 4. 4 is less than 5 so 4 is the next number to be chosen. Lastly, since 5 and 7 are already sorted by themselves and they have not been chosen, they will be the next 2 numbers. We repeat this process with the other two pairs and we end up with…

2, 4, 5, 7          1, 3, 9, 12

To finish the algorithm, we compair the two sets of numbers and combine them to create our final sorted array of 1, 2, 3, 4, 5, 7, 9 , 12.

I quickly wrote up a merge sort implementation in java for you guys to view.

public void mergeSort(int low, int high, int[] num) {
        if(low >= high)
            return;
        int mid = (low + high)/2;
        mergeSort(low, mid, num);   //left side
        mergeSort(mid + 1, high, num);  //right side
        merge(low, mid, high, num); // merge the two
    }
    
    public void merge(int low, int mid, int high, int[] num) {
        int[] holder = new int[num.length];
        int index = low;
        // insert values into holder array
        for(int i = 0; i < num.length; i++) {
            holder[i] = num[i];
        }
        
        int leftIndex = low;    //iterates through holder
        int rightIndex = mid + 1; //iterates through holder
        int numIndex = low;  //iterates through num[]
        
        while(leftIndex <= mid && rightIndex <= high) {
            if(holder[leftIndex] <= holder[rightIndex]) {
                num[numIndex] = holder[leftIndex];
                leftIndex++;
            } else {
                num[numIndex] = holder[rightIndex];
                rightIndex++;
            }
            numIndex++;
        }
        
       while(leftIndex <= mid) {
            num[numIndex] = holder[leftIndex];
            leftIndex++;
            numIndex++;
       }
    }

In reality, and if I wasn’t being lazy, it would be considered better practice to implement a merge sort object where you would pass in the array of integers to be sorted into the object constructor. From there you could perform whatever sorting that is needed on the array. This would eliminate the need to pass the array of numbers through the mergeSort and merge functions.

Nov
12

Even Occurrence

I’ve been slacking quite a bit the past few days on making a post, so today I’de thought I would go over the problem I was asked in my first Amazon phone interview.

Write a function that takes in an array of integers and returns the integer that occurs an even number of times. You are guaranteed that only one integer occurs an even number of times.

My implementation was relatively simple. I used a hash table to store integer value and integer count pairs. So, while iterating through the array, we check to see if the value exists in the hash table. If it doesn’t, we insert this value into the table and give it a count of 1. If it does exist, we increment the count value attached to it.

After iterating through the whole array once and storing values in the table, we begin iterating back through it until we find a value in the hash table that has occurred an even number of times. The run time for this would be O(n+m).

What if we ask the question a different way? What if the task is to write a function that returns the integer that occurs an odd number of times? The method I used above still works fine, BUT, there is an even better way of doing this. It turns out, that if you XOR the whole array together, you end up with the answer. This means we don’t need to create a hash table or any extra data structures, and we only need to iterate through the array once. So the run time for this would be O(n) and space would be constant!

Nov
07

Amazon Interview

The following interview is NOT my interview experience but, a friend’s on site interview at Amazon.

My friend, who is currently pursuing a masters degree in Computer Science was contacted by an Amazon recruiter. He never applied to Amazon, but he thinks they found his resume through the University career services or his Monster.com listing. Either way, he was contacted and was flown up to Seattle for interviews. They allowed him to skip the phone interviews.

He was flown up the day before and they had a room reserved for him at a nearby hotel. The next morning he headed over to the Amazon campus where he would spend the rest of the day in technical interviews with 4 different people (about 45 minutes each). Three of the interviewers were part of the team he was interviewing with and the other interviewer was from outside the team whom they called the “bar raiser”. Below are the questions he was asked throughout the day.

1. Write a method with the following definition:
boolean containsSubstring(String input, String search) and returns true if the search string appears in the input string (obviously you can’t use .contains).

2. Write a method that takes a linked list and flips all the pairs. ex:
a->b->c->d
b->a->d->c
basically, every pair is flipped with the prev/next (but only like pair to pair).

3. Write a method that takes two sorted lists of ints and returns a sorted list with the combination of the lists.

4. Write a method that takes K sorted lists of ints and returns a sorted list with the combination of the lists.

5. Given a map with points and a location, find the closest point to the location.

6. Given a map with points and a location, find the closest K points to the location.

7. (This problem was just carried on for a bit with a lots of little alterations)

8. Write a method that would take an int[][] and return the transpose.

9. Write a method that would take an int[][], an (x, y) and an int value (basically the object of this is to design a paint bucket feature, where if you click anywhere in on solid color it changes them all to a new color).

Nov
06

Autonomous Slot Car System

At the University of Texas at Arlington, Computer Science students must complete a course called Senior Design. It is a two semester long course, and during this time, we work on teams of 4 developing the documentation, requirements, architecture design, detailed design, and a test plan for our final project. In my case, our project was an autonomous slot car racing system that allowed a human player to race against a computer controlled car in real time. By the end of the second semester, we had a fully operational system that could do the following.

  • Allow a race between a human and computer opponent
  • Human controlled their car with an xbox 360 controller
  • Track the cars using a camera
  • Keep track of lap times for each lap
  • Declare the winner and loser
  • The computer had 3 difficulty settings
  • Disqualify the human player if the car flew off the track
  • The user could change the number of laps in a race
In the end, the system worked pretty well. Not completely flawless of course given that we only had 2 weeks to actually implement everything but it worked about 95% of the time. I’ve provided links to all of the documentation that was done during the project below. Pretty boring but hey, maybe you will think they are interesting

Nov
02

Prime Numbers

The challenge for today has to do with prime numbers. The goal is to write a function that takes in an integer x and prints out all of the prime numbers that are less than x. First of all, what exactly is a prime number? A prime number is an integer that is only divisible by 1 and itself. As an example, what should this function print if we pass in the value of 10?

2,3,5,7    (Note that 1 is NOT a prime number)

So first, lets look at the obvious solution.

void printPrimes (int x) {
    for(int i = 2; i < x; i++) {
        if (isPrime(i))
            System.out.print(i + ",");
    }
}

boolean isPrime (int y) {
    int count = 2;

    while (count < y) {
        if (y % count == 0) {
            return false;
        }
        count++;
    }
    return true;
}

Each time, we will check if the integer we are about to print is prime or not. Every time we check if a number is prime or not, we divide it by all of the numbers below it and see if we get a remainder. If we do not get a remainder then the number is not prime. By doing this though, we repeat much of the work we’ve already done and get a worst case runtime of O(n) + [O(n) + O(n-1)+...+O(1)] (roughly). So, how can we make this more efficient? There is a rule that says that all composite numbers can be made by multiplying prime numbers together. By keeping track of the known primes, we can check if a number is prime by dividing it by all of the known primes below it. So here is what I came up with.

public ArrayList<Integer> primes;

void printPrimes (int x) {
    primes = new ArrayList<Integer>();
    addPrimes(x);
    for(int i = 0; i < primes.size(); i++) {
        System.out.print(primes.get(i) + ",");
    }
}

void addPrimes(int x) {
    int count = 3;
    while (count < x) {
        if(isPrime(count)) {
            primes.add(count);
        }
        count++;
    }
}
    
boolean isPrime(int x) {
    for(int i = 0; i < primes.size(); i++) {
        if (x % primes.get(i).intValue() == 0){
            return false;
        }
    }
    return true;
}

Instead of dividing by every integer below itself to check if a number is prime, we only check the primes we have already found. I’m sure there are more things we can do to optimize this further. If you have any suggestions let me know in the comments!

Nov
01

Mth to the Last

Technical interviews can be a challenge. You can attempt to prepare for everything, but it’s pretty much guaranteed that you will be asked a question you weren’t expecting. So, you should be prepared to solve that unexpected question on the spot. How do you prepare for this question? PRACTICE!

I often like to practice my programming / problem solving skills by solving programming puzzles I find on the web. Today, I worked on a problem called Mth to the last element. The goal is to write a function that will take in a linked list and a number m and return the mth to the last element in this linked list. We’ll assume that this is a singly linked list as a doubly linked list would make this problem trivial.

Alright, so what is the obvious answer? My first thought is to use a stack. We would push each element in the linked list onto the stack. Once the whole list has been pushed onto the stack, we pop the elements off m number of times. Pretty simple solution at first glance. The worst case runtime would be O(2n) and memory would be O(n). This isn’t too bad, but is there anyway we can get rid of the stack and not have to create a stack containing our list?

Lets assume n is the entire length of the list and m is the number of elements from the end of the list. Can we calculate how many elements starting from the front of the list the goal element is? n  - p = m where p is the number of elements from the front of the list the mth to the last element is. So knowing this, we can iterate through the list once to find the value of n and then iterate through the list again until we hit the pth element which is also the mth to the last element. This would give us a worst case runtime of O(n+p) which could technically be O(2n) if m = 0. The O(n) space requirement is gone though because we don’t need to store the list in the stack. So this is an even better solution!

An O(2n) runtime is really good, but there is a way we can make this even better. See if you can figure it out on your own and leave a comment if you have any questions.

Oct
29

Amazon Phone Interview #2

I was pretty enthusiastic about making it past the first phone interview and prepared for the second. This time, the interviewer set up a shared google docs document for me to write code in. I much prefer this to the previous interview where I had to read all of the code, brackets and all to the interviewer over the phone. It may have been my saving grace as well since I had a lot of trouble understanding the interviewer’s accent in combination with bad reception. The question asked of me was pasted into the document for me and was read as follows:

“there are 2 lane road . one lane headed north and other south. there are 2 traffic sensors A and B . A crosses only north lane and B crosses south lane .
there is collector box that records the timestamps of events on A and B.
write a function that takes 2 input arrays of timestamps , one from A and one from B . and calculates the number of cars headed north . number of cars headed south . and avg speed of car for north lane, avg speed for south lane.
return this information in some data structure.”
The above question is posted verbatim exactly as it was written to me in the document, so excuse the bad grammar. My initial thoughts after speed reading through it was that both traffic sensors crossed both lanes which would have made this extremely hard. However, after reading back through I noticed that they only crossed one lane each, which makes the problem relatively trivial. What you have to realize is that every car has 2 sets of tires and as a result, every car gets two time stamps. Therefore, the number of cars in a given lane is the array.length/2. To find the average speed of the cars, I asked the interviewer if I could assume that the distance between the cars two sets of wheels were all the same. She was fine with that, so the speed of each car is the (distance/BackWheelTime-FrontWheelTime). Average all of the speeds together and you have the average speed. Return all of this information in a data structure and you’re done.
Overall, I wasn’t too impressed with this interview. This didn’t really seem like a true technical interview question. I think anyone in a beginning programming course should be able to figure this out. On top of that, the fact that you needed to calculate everything for both lanes was a bit redundant and I spent much of my time copying and pasting code and changing variable names to implement the logic for both lanes. In the end I felt I did well on both interviews but apparently they did not agree. I would not be flown in to Seattle for an in person interview. Maybe next time.

Oct
27

Amazon Phone Interview #1

I get contacted by an Amazon recruiter who wants to schedule a phone interview with me. I accept and the date is set a week from when I was contacted. During this time I study like crazy to prepare myself. When you get an opportunity with a company like Amazon, you don’t want to screw it up. I ended up buying the book “Programming Interviews Exposed” and read it all within the week. I highly recommend this book if you are about to go through any technical interviews. Anyways, the day of the interview hits and I get an e-mail from the recruiter saying something had come up and the interviewer would be busy. No big deal, I realize things can happen, so we rescheduled it for a week later.

So the next week I get the call from the interviewer, had paper and pencil ready as they were going to ask me to write code for some of the questions. The interview starts out as expected by the interviewer introducing himself and telling me about his position at the company and what he and his team do. He asks me a few things about myself and some of the things on my resume and we move onto the questions since we have a limited amount of time.

The first few questions were your standard OO questions. What is inheritance? What is Polymorphism? What are they used for and why do they make it easier to program ect…

Then we moved on to my first programming problem. Write a method that takes in a string and returns true if the ( ) are balanced in the string and false if it not balanced. Easy enough. My first solution was to use a stack to push ‘(‘ onto the stack and pop the ‘(‘ off the stack if we see a ‘)’. If we ever encounter a ‘)’ and the stack is empty we return false. Also if we are finished iterating through the string and the stack is not empty then we also return false, otherwise we return true.

He seemed happy with this solution and then asked if there was any way to do this without using the stack data structure. After thinking I realized that all you have to do is keep a counter. Start it at 0, increment when you see ‘(‘ and decrement when you see a ‘)’. Felt a bit dumb I didn’t notice that the first time through, but I see it as a good thing that I found two methods of solving the problem.

For the second question he asked the following: Write a method that takes in an array of integers, find the integer that occurs an even number of times in the array. You are guaranteed that this number will be the only number that occurs an even number of times.

For example, in an array that contains, 1,2,3,1 you would return 1.

Was an interesting problem but I solved it pretty easily in O(n) time. Try to figure it out on your own, if you want to know my solution then leave a comment.

That was it for the interview. I felt it went really well and a week later I was contacted by the recruiter to schedule a second phone interview.