Square Root
Last updated
Last updated
Implement int sqrt(int x). This function computes and return the square root of x.
Note: this question is asking for an integer. So (int) Math.sqrt(x) shall we? Well, the question is asking you to implement... No clue? Here is .
11/26/2016 New Note: Do you recall find the last index? Ohhhhh
Not something we can generalize. But it's easy to understand and gives an elegant solution to this problem.
Get an arbitrary x that is greater than 0. If is too big, then will be too small. (or is too small, then will be too big. This case occurs when ). Their average will be closer to our target .
Note 1: If you use double for xn, the program will not terminate. It will approximate to the last digit that double has then stops there. We'll discuss how to implement double later.
Note 2: xn should use long instead of int to handle the extreme case where xn * xn causes integer overflow (ex. mySqrt(Integer.MAX_VALUE))
This is an implicit binary search question. It asks you to search on the results instead of searching for an index in a given array.
We pick 1 (left) and x (right) (or but that only saves one iteration). Use binary search to find an x such that . The tricky part for a bs is to know when to stop. In here, we choose the "lazy" way - break the loop when left and right are next to each other. In the end, we just have to add an extra check to see return left or right.
Other options: 1. left <= right
needs return right in the end (left > right to break the loop). Also, left and right needs to move away from mid (i.e. left = mid + 1 and right = mid - 1). Otherwise, left > right never happens and we are stuck in the loop ᶘ ᵒᴥᵒᶅ. 2. left < right
The loop breaks when left == right. But this is too late! What if sqrt(10) = 3 (3*3 < 10)? One way to fix this is to add some sandwich check for mid ex. mid <= x/mid && mid+1 > x/(mid+1).
O(log(x))
What if we want a double instead of an integer? Implement double sqrt(double x).
Binary search (or Newton's) is still a good choice. Our first task is to figure out when to stop. We need to define an to cap the error in our approximation.
Note: 0 < x < 1 is a special case because can be smaller or bigger than x. So we need Math.abs for the error. Ex. Whereas, when x > 1, will always be too big until the loop breaks.
Same as Newton's, we need an and have to take care of the special case where 0 < x < 1. We need to have two separate searches 0 to 1 and 1 to x. 0 to x will cause infinite loop when 0 < x < 1. (ex. x = 0.7 but need to return 0.836).
\ʕ •ᴥ•ʔ/
Roughly O(log(n)) More from 6.006
Let's end with .