I am trying Leetcode Question - 69. Sqrt(x)
Given a non-negative integer x, compute and return the square root of x.
Since the return type is an integer, the decimal digits are truncated, and only the integer part of the result is returned.
Note: You are not allowed to use any built-in exponent function or operator, such as pow(x, 0.5) or x ** 0.5.
class Solution {
public int mySqrt(int x) {
int ans = 0;
int i=1;
while(i*i<=x){
ans = i;
i++;
}
return ans;
}
}
This is the code I came up with. But the testcase input=2147395600 is not passing.
My Output = 289398
Expected Output = 46340
I'm confused as I have put the condition i*i<=x, then how can ans be more than the sqrt value?
Since you are comparing i * i with the input x, if the input x is too close to Integer.MAX_VALUE (2.147.483.647), like in that test case, i * i will be bigger than the maximum value allowed for an int to have and i*i<=x will be true.
Possible solutions:
Implement a binary search algorithm where max would be the floor(sqrt(Integer.MAX_VALUE)) or 46340.
Implement a algorithm where ans, i and x are declared locally as long type variables and in the return line you return the value cast to int using return (int)ans;
By running the following algorithm you can see the limit of a java int exploding and what happens afterwards.
int x = 2;
while(true) {
System.out.println(x);
x *= 2;
}
Not pretending to be fast, just the idea that (n+1)2=n2 + 2n + 1:
public static int mySqrt(int x) {
int i = 0;
while (x >= 0) {
x -= (i++ << 1) + 1;
}
return i - 1;
}
My JavaScript Solution
var mySqrt = function(x) {
var ans = 1;
if(x === 0){
ans = 0;
} else {
for (let i = 1; i< x;i++){
if(i*i === x){
ans = i;
break;
}
if(i*i >x){
ans = i - 1;
break;
}
}
}
return ans;
};
A friend challenged me to write a program that gets three integers (int a, int n, int k) and computes efficiently as possible, a^n mod k
I came up with this solution
public static int rec(int a,int n,int k) //calc a^n mod k
{
if(n == 1)
return a % k;
int exp1 = rec(a, n/2, k), exp2 = exp1;
if(n % 2 == 1)
exp2 = rec(a, n/2 + 1, k);
return (exp1 * exp2) % k;
}
It's an incredibly simple recursive solution, reliant on the fact that a^(b+c) mod d = (a^b mod d * a^c mod d) mod d, and runs in logarithmic time. At least theoretically.
In practice when we measured our solution, his linear time solution was better than my solution. I suspect it's due to me using recursion rather than loops. Does that make sense? If so - how can I turn this code into an iterative program?
Does that make sense?
Yes. As Boris The Spider pointed out, there is no tail optimization in Java.
how can I turn this code into an iterative program?
Let me copy-paste an iterative solution to calculate power of a number from here
int pow(int x, int n) {
int res = 1;
while(n > 0) {
if(n % 2 == 1) {
res = res * x;
}
x = x * x;
n = n / 2;
}
return res;
}
Disclaimer : Although the above code looks ok to me, I haven't tested it personally.
public class Prod {
public static void main(String[] args) {
System.out.println(prod(1, 4));
}
public static int prod(int m, int n) {
if (m == n) {
return n;
} else {
int recurse = prod(m, n-1);
int result = n * recurse;
return result;
}
}
}
This is an exercise in the book I am stumped on. Why would the program not just recurse until the two numbers are equal and then return n ? Also, where it says,
int result = n * recurse;
How does it multiply int n by recurse which would be (int, int)? How can it multiply one integer by a set of two integers?
In what way am I misunderstanding this program?
EDIT: This is a different question because I am not using factorials
prod(x,y) is equivalent to y! when x=1.
If x is different from 1, then its doing recursive multiplication (y * (y- 1) * (y -2) .... ) until y = x.
Assuming y > x.
By the way, if x > y then prod() will crash.
So I decided to try out Codility. The first task - FrogJmp was ridiculous easy, however to my surprise I scored 44%. Solution, even if correct was obviously unacceptable in terms of performance.
Original solution:
public int solution2(int X, int Y, int D) {
return (int) Math.ceil((float)(Y -X)/D);
}
So I decided to try it with different code, without floating point arithmetic.
public int solution(int X, int Y, int D) {
int diff = Y - X;
if (diff % D == 0)
return diff /D;
else
return diff/D + 1;
}
This time I got 100%. So I wanted to check the performance myself and wrote simple test:
class Solution {
public int solution(int X, int Y, int D) {
int diff = Y - X;
if (diff % D == 0)
return diff /D;
else
return diff/D + 1;
}
public int solution2(int X, int Y, int D) {
return (int) Math.ceil((float)(Y -X)/D);
}
private static Random ran = new Random(System.currentTimeMillis());
public static int getRandom(int a, int b){
return ran.nextInt(b - a + 1) + a;
}
public static void main(String[] args) {
int size = 1000_000;
int max = 1000_000_000;
int[] xs = new int[size];
int[] ys = new int[size];
int[] ds = new int[size];
for (int i = 0; i < size; i++) {
int y = getRandom(1, max);
int x = getRandom(1, y);
int d = getRandom(1, max);
xs[i] = x;
ys[i] = y;
ds[i] = d;
}
long start = System.nanoTime();
Solution sol = new Solution();
for (int i = 0; i < size; i++) {
sol.solution2(xs[i], ys[i], ds[i]);
}
long diff = System.nanoTime() - start;
System.out.println("took: " + diff/1000000 + "ms");
}
}
To my surprise, on my machine the solution 1 takes on average 13ms and solution 2 (the one reported as absolutely ineffective) 10 ms.
What am I missing?
Maybe it has to do something with expected time and space complexity of the tasks.
expected worst-case time complexity is O(1); expected worst-case space
complexity is O(1).
Does not solution 2 have constant time & space complexity?
Also I cannot make sense of this results report for 44% solution:
What does it mean??
100/100 solution in C# I just
using System;
class Solution {
public int solution(int X, int Y, int D) {
return ((Y - X) + D - 1)/D;
}
}
Solution in Java 100/100 and O(1) time complexity.
public int solution(int X, int Y, int D) {
return Double.valueOf(Math.ceil((Y - X) / (double) D)).intValue();
}
Both solutions have O(1) time complexity. The problem is that the first solution is returning wrong answers. The performance tests test the answer as well as the time. Your solution failed probably because of precision issues with the use of floats.
For x = 1, y = 1000000000, d = 1, your first solution gives 1000000000 as an answer, and the second gives
999999999. Changing from (float) to (double) corrects this result.
In these algorithm tests, it's usually a good idea to avoid floating point arithmetic as much as possible to make it easier to get the exact answers for all cases.
OBJECTIVE-C SOLUTION O(1)
Results given by Codility
Task Score: 100%
Correctness: 100%
Performance: 100%
Time Complexity
The worst case time complexity is O(1)
Xcode Solution Here
+(int)solution:(int)x y:(int)y d:(int)d {
/******** Algorithm Explanation ********/
// FACTS
// I realized that the formula: [x+(n*d)] >= y satisfies the required frog jumps
// then, the formula to find the 'n' required jumps is the following:
// n = (y-x)/d
// STEP 1
// Implement the formula in code
// Be careful dealing with the floating point, it should be double
// use the function 'ceil' as a resource to round to the next integer.
double n = ((double)y - (double)x) / (double)d; // O(1)
n = ceil(n);
return (int)n;
}
Solution in Java 100/100 and O(1) time complexity:
public int solution(int X, int Y, int D) {
int diff = Y - X;
int count = diff / D;
if (diff % D > 0) {
count++;
}
return count;
}
JS Solution
Task Score: 100%
Correctness: 100%
Performance: 100%
function solution(X, Y, D) {
return Math.ceil((Y - X) / D);
}
Solution in C#
double result = (Y - X) / (D * 1.0);
return Convert.ToInt32(Math.Ceiling(result));
public static int solution(int X, int Y, int D) {
// write your code in Java SE 8
return (int)Math.round((Y-X)/(double)D);
}
This will also fetch 100%
Tried this one for 100/100
public static int frogJmp(int X, int Y, int D) {
return (int) Math.ceil( (Y-X) / (double)D );
}
Simple O(1) solution in Java:
class Solution {
public int solution(int X, int Y, int D) {
return (Y-X) % D == 0 ? (Y-X) / D : (Y-X) / D + 1;
}
}
Count minimal number of jumps from position X to Y.
public int solution(int X, int Y, int D) {
if (X == Y)
return 0;
else if ((Y - X) % D == 0)
return ((Y - X) / D);
else
return ((Y - X) / D) + 1;
}
First, you should pay attention to divisor which can not be 0 in your case "diff / D", D can not be 0.
Second, in your case "diff = Y - X", if ( diff <= 0 ) then you don't to jump anymore.
Frogjump solution in C
int solution(int X, int Y, int D) {
// write your code in C90
int r=0;
if(Y>X)
{
r=(Y-X)/D;
if((X+(r*D)) < Y) r++;
}
return r;
}
public int solution(int X, int Y, int D) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
double divAll = (Y-X) / (D * 1.0);
double finalRes = (Y-X) % (D * 1.0) > 0 ? (divAll + 1) : divAll;
return (int) finalRes;
}
Here is my 100% / 100% solution
public int solution(int X, int Y, int D) {
double d = D;
return (int) Math.ceil( (Y-X) / d );
}
I just resolved it with perfect score, So this is my answer (java):
static int solution(int X, int Y, int D){
double count=((double)Y-(double)X)/(double) D;
return (int)Math.ceil(count);
}
For the first time i thought it could be rdone by using "While loops" but i got zero performance..
Here is my simple code with detected time complexity of O(1) in Codility.
public int solution(int X, int Y, int D) {
int dev = (Y - X) % D;
if (X == Y)
return 0;
else if (dev == 0)
return (Y - X) / D;
else
return ((Y - X) / D) + 1;
}
Solution 100% in JS
function solution(X, Y, D) {
const distance = Y - X;
if (distance % D === 0) {
return Math.round(distance/D);
}
return Math.floor(distance/D +1);
}
I've having some trouble with recursion. At the moment, this code gives me an error message "missing return statement". Any way to get this working the way I want it to? I want it to calculate for xn and then return "count" when n reaches zero.
public class Question6p2 {
public static void main(String[] args){
int n = -6;
int x = 2;
int count = x;
power2(n, x, count);
System.out.println(power2(n, x, count));
}
public static int power2(int n, int x, int count){
if (n != 0){
if (n>0){
count = count * x;
n = n - 1;
}
else if (n<0) {
count = count * -x;
n = n + 1;
}
power2(n, x, count);
}
else if (n == 0){
return count;
}
}
}
Maybe I'm coming about this all wrong. Anyone care to help?
Currently, you have this statement:
power2(n, x, count);
... which ignores the result completely. In that branch, we never return anything from the method call. I suspect these two issues are linked.
I suspect you just want:
return power2(n, x, count);
Currently you are getting an error about not having a return statement because your return statement is within an if statement, so if that if statement doesn't run you will not return anything which is a problem.
Also I think you are going about recursion fundamentally wrong, as you are never calling back to your method recursively.
What you probably want to do within your power method is to accept n as the number of time to call your method, then lower it by 1 with each recursion. Then on every recursion multiply x by the original value.
Here is what I mean:
public static double power2(int n, int x,int xOriginal){
if(n == 0){
return 1;
}
if(n < 0){
return 1 / power2(n*-1, x, x);
}
if(n <= 1){
return x;
}
return power2(n -1, x * xOriginal, xOriginal);
}
Edit: Works with negative n now.
There are a few things wrong with your algorithm:
What does it mean to have a negative exponent?
You should understand that x-n can be written 1 / xn. This is not what was reflected in your algorithm.
All possible cases
There are 4 basic cases when calculating exponents.
There is any value x0 = 1.
Any x1 = x
Any negative exponent x-n = 1 / xn
Any positive exponent greater than one: xn where n > 1
Your algorithm should return 1 when x has an exponent of zero. Return x when the exponent is 1 or recursively call the algorithm when n > 1.
In the special case where n < 0 (ie you have a negative exponent) You can simply return the reciprocal 1 / method() as long as you change the sign of n before calling the method.
The line:
else if (n < 0){
n = -n;
return(1 / power2(n, x, count));
}
Checks for negative exponents, and returns 1 / xn Take note that the sign of n changed here, and now this is operating like any other method call with positive exponents.
public class TestCode {
public static void main(String[] args){
int n = 4;
int x = 5;
double count = x;
System.out.println(power2(n, x, count));
}
public static double power2(int n, int x, double count){
if (n == 0)
return 1;
else{
if (n > 1){
count = count * x;
n = n - 1;
}
else if (n < 0){
n = -n;
return(1 / power2(n, x, count));
}
else if (n == 1) {
return count;
}
return power2(n, x, count);
}
}
}