Saturday, May 28, 2011

How to find if a number is perfect square

Number problems are abound in the programming interview world. A perfect square (also called a square number) is an integer that is the square of an integer; in other words, it is the product of some integer with itself. So, for example, 9 is a square number, since it can be written as 3 × 3. So are 16, 25, 49 and so on.

So how do we find if a given number is a square number or not? There are a many ways. This is a big research topic in the mathematics world. For the purpose of interview, we will not delve into highly complex solutions.

A bad implementation would be something like this:

publicstaticbool IsSquare(long target){// loop through all the numbers till the targetfor (long i = 0; i < target; i++) {// if we have a matchif ((i * i) == target) {returntrue; } }

// no matching number could be squaredreturnfalse;}

This is an inefficient solution. There is no need to loop till the element. The only case when this would be true is 1. Beyond that, if a number is a square, it’s square root has to be less than half of the number (4 – 2, 9 – 3, 16 – 4, 25 – 5 an so on. Let’s modify our algorithm to add this logic.

Even though we have cut our loop by half, this is still inefficient. So what can we do more to stop the loop earlier. Let’s assume that our target number was 20. So using the code above, we will be looping till 10. Now once the loop crosses 5, we know that none of the numbers above that will result in the loop being true. So, a good condition to add would be break if the square of the current number is greater than the target. Let’s review this code below:

// loop through till the target is more than// the square of the current numberwhile (currentSquare <= target) {// if we have a match, return trueif (currentSquare == target)returntrue;// increment current number currentNumber++;// find the next square currentSquare = currentNumber * currentNumber; }

// no matching number could be squaredreturnfalse;}

Yes, this is still not the best solution but these code snippets should give you a good enough idea on how to optimize this algorithm further. I challenge the readers to take a few minutes out and come up with a better solution.

I made some tests here and noticed that using this method I loose some time in performance. Of course, this is a very tiny difference, but there are. However, I'm not sure if I built this if statement correctly... Seems like I have to do a lot of things to accomplish it.

@JacobThe point is in programming interviews you'll be asked not to used libraries. Otherwise, if the interviewer asks you to write a function for binary search, you could write:return System.Array.BinarySearch(...);Hahaha!

You could do a binary search instead. Start with i = median(n). Then compare i^2 with n to determine which direction to go. Repeat until you have an i value such that i^2 == n or until you've exhausted all viable possibilities. Run-time is O(lg n) assuming multiplication is a constant-time operation.

// make an initial guess and store as a floating point. // the divisor is arbitrary, testing would have to be done to choose an optimal value // basically the closer the initial value the faster the solution double guess = input /2.0;

// uses approximation equation for 20 iterations or until the guess is close enough // the max number of iterations could be adjusted for(int i = 0; i < 20; i++) { // if the guess, is correct it will exit the loop. if( guess * guess == input) { return true; }

This could be solved in a constant time O(C), given that integers have fixed bit-size. Digit-by-digit algorithm will have O(M) complexity, where M is number of bits in integer. Still the implementation is somewhat complicated.

One can keep adding odd integers starting from 1, until the sum matches the number (ansewer=yes) or exceedes (answer=no).1 = 1^21+3 = 2^21+3+5 = 3^2....This is still a linear solution but addition is cheaper than multiplication.

The blog or and best that is extremely useful to keep I can share the ideas of the future as this is really what I was looking for, I am very comfortable and pleased to come here. Thank you very much.tanki online | 2048 game|