how can i write a recursive function of my pseudocode? - java

Actual code is easier but I'm having trouble finding the base case as well. I was able to write pretty decent pseudocode, but I'm having trouble. I don't know if I'm allowed to ask homework questions on here, but this was a question I could not answer:
Let f(n) be the number of additions performed by this computation.
Write a recurrence equation for f(n). (Note that the number of
addition steps should be exactly the same for both the non-recursive
and recursive versions. In fact, they both should make exactly the
same sequence of addition steps.)
Any help would be great, if I'm not allowed to ask the homework question that's okay.
int sum(int A[], int n ):
T=A[0];
for i = 1; to n-1
T=T+A[i];
return T;}

Use the following property of your sum function:
sum(A[], n) == sum(A[], n-1) + A[n]
and take into account that:
sum(A[], 1) == A[1]

Just re-wrote your variant
int sum(int A[], int n ):
if (n > 1){
T=A[n-1] + A[n-2];
T += sum(A, n-2)
}else{
if (n > 0) { return A[n -1];}
}
return T;
}

Related

Determining the Big O of a recursive method with two recursive cases?

I am currently struggling with computing the Big O for a recursive exponent function that takes a shortcut whenever n%2 == 0. The code is as follows:
public static int fasterExponent(int x, int n){
if ( n == 0 ) return 1;
if ( n%2 == 0 ){
int temp = fasterExponent(x, n/2);
return temp * temp;
}
return x * fasterExponent(x, --n); //3
}
I understand that, without the (n%2 == 0) case, this recursive exponent function would be O(n). The inclusion of the (n%2 == 0) case speeds up the execution time, but I do not know how to determine neither its complexity nor the values of its witness c.
The answer is O(log n).
Reason: fasterExponent(x, n/2) this halfes the input in each step and when it reaches 0 we are done. This obviously needs log n steps.
But what about fasterExponent(x, --n);? We do this when the input is odd and in the next step it will be even and we fall back to the n/2 case. Let's consider the worst case that we have to do this every time we divide n by 2. Well then we do the second recursive step once for every time we do the first recursive step. So we need 2 * log n operations. That is still O(log n).
I hope my explanation helps.
It's intuitive to see that at each stage you are cutting the problem size by half. For instance, to find x4, you find x2(let's call this A), and return the result as A*A. Again x2 itself is found by dividing it into x and x.
Considering multiplication of two numbers as a primitive operation, you can see that the recurrence is:
T(N) = T(N/2) + O(1)
Solving this recurrence(using say the Master Theorem) yields:
T(N) = O(logN)

Recursive method for prime numbers in JAVA

First of all I know this is kind of a simple question and I am a beginner so please bear with me .
I have been having problems with this exercise in Java and I'm practising for a test and this one really messed up my self-confidence.
So anyways the problem looks like this
// Returns true if (and only if) n is a prime number; n > 1 is assumed.
private static boolean isPrime(long n) {
return isPrime(n, 2);
// See the method isPrime below.
}
// Helper method for isPrime ...
private static boolean isPrime(long n, long m) {
return (m * n > (m /* TODO: modify expression if necessary */))
|| (n % m == (0 /* TODO: modify expression if necessary */)
&& isPrime((m /* TODO: modify expression if necessary */), n + 1));
}
So you're supposed to fill these expressions inside of the brackets where TODO is .
My problem is that I just can't trace what this does.
isPrime((.....),n+1);
If someone could just offer some advice on how to start solving this problem I would be very grateful .
This problem is not amenable to recursive solution. Or at least not an efficient recursive solution.
The definition of primality is that N is prime if it is not divisible by any positive integer other than itself or 1. The normal way to handle that using recursion would be to define a recursive "is_divisible" function:
# for integers m >= 1
is_prime(m):
return is_divisible(m, 1)
is_divisible(m, n):
if n >= m: return true
if n == 1: return is_divisible(m, n + 1)
if m % n == 0: return false // HERE
return is_divisible(m, n + 1)
OR (more efficient 3 parameter version)
# for all integers m
is_prime(m):
if m == 1: return false
if m >= 2: return is_divisible(m, sqrt(m), 2)
error "m is not a positive integer"
is_divisible(m, max, n) :
if n >= max: return true
if m % n == 0: return false // HERE
return is_divisible(m, max, n + 1)
(In the literature, they often call functions like is_divisible "auxiliary" functions. This is a common tool in functional programming.)
If you try to "optimize" that to only consider prime numbers at HERE, you will end up with double recursion .. and exponential complexity.
This is all very "unnatural" in Java, and will be horribly inefficient (even compared with a naive primality test using a loop1) because Java doesn't do tail-call optimization of recursion. Indeed, for large enough N you will get a StackOverflowError.
1 - A better, but still simple approach is the Sieve of Erathones. There are better tests for primality than that, though they are rather complicated, and in some cases probabilistic.

How to show that the time complexity of algorithm is O(2^n)?

I'am doing a practice interview question from HackerRank Coin Change
I got stuck and I'm trying to understand a Solution to this problem. Here is the recursive solution to this problem.(with my comments to understand it)
public static int numWays(int[] coins, int sumTo) {
return numWaysWhichCoin(coins, sumTo, 0);
}
private static int numWaysWhichCoin(int[] coins, int sumTo, int whichCoin) {
if(sumTo == 0) {
//empty set
return 1;
} else if(sumTo < 0) {
//no way to form a negative sum with positive coin values
return 0;
} else {
//sumTo is positive
//case gone through all the coins but still a positive sum. Impossible
if(sumTo > 0 && whichCoin == coins.length) {
return 0;
}
//with and without. With, you can keep using the same coin
return numWaysWhichCoin(coins, sumTo - coins[whichCoin], whichCoin) + numWaysWhichCoin(coins, sumTo, whichCoin + 1);
}
}
The author states that the algorithm runs in O(2n) time complexity. From my experience in interviews, you are expected to justify your answers.
How wold you justify this time complexity? From my previous work to showing algorithms run in O(2n) time, I would use recurrence relations, like(Fibonacci) T(n) = T(n-1) + T(n-2) +c <= 2T(n-1) + c, T(1) = d, but I can't derive a recurrence relation like that from here. Is there another way of going about this justification?
The two recursive calls make it act like a binaric tree that grows in 2 n rate.
Your algorithm as far as complexity is identical to Fibonacci recursive algorithem. So you can look and find the many answers and explenations and even proofs why recursive Fibonacci is from the order of 2 n.
Suppose there are R different combinations (the requested result).
The number of coins of the i-th coin (0<=i<=M-1) used in a specific solution r (0<=r<=R-1) is C(i, r). So for each r in 0...R-1 we have C(0,r)+C(1,r)+....C(M-1,r)=N.
The maximum value of C(i, r) for each r in 0...R-1 is max_c(i)=floor(N/Vi) (Vi is the value of coin i), which less or equal to N.
The sum of c_max(i) where i=0..M-1 is <= N*M. So the total number of individual coins used in all the combinations is O(NM).
The algorithm you presented simply iterates all the sub-groups of the group above of c_max(i) individual coins for each coin value Vi, which O(2^(NM)).

Recursion in Matlab vs Java

I hacked up a recursive function in Java for a homework problem in my Stats class, that looked something like this:
public static int d (int k, int n) {
if (n == 1) return 1;
else if (n > k) return 0;
else return n*d(k-1, n) + n*d(k-1,n-1);
}
I then plugged (20, 8) into this function, and got 998,925,952. My professor, however, said that this answer was wrong, and after rethinking my code over and over again, I decided to try the same thing in Matlab:
function t = d(k,n)
t = 0;
if n == 1
t = 1;
elseif n > k
t = 0;
else
t = n*d(k-1, n) + n*d(k-1, n-1);
end
This function, apparently, gave me the right answer with the above input, 6.1169 * 10^17.
This has been bugging me all day, and I have absolutely no idea why two seemingly identical programs in two different languages would give me completely different results. Can anyone help explain this?
Your Matlab routine is probably working on floating-point input, so it will compute in floating-point.
Your Java routine has integer types; 6.1169e17 is way outside the supported range, so it overflows. Try changing your types to float or double.
611692004959217300 is much larger than 2147483647 which is the integer MAX_VALUE in Java.
I got 611692004959217300 by running
function d (k, n) {
if (n == 1) return 1;
else if (n > k) return 0;
else return n*d(k-1, n) + n*d(k-1,n-1);
}
console.log(d(20,8));
in Firebug.
Consider what the maximum value an int can have, which is what you've got in Java. Now consider what the maximum value a double can have, which is MATLAB's default type.
Java integers are 4 bytes in size, so the number looks too big (greater than 2^31). You should try again using "long" or "double" as datatype for your variables.

How to test if an array contains a pair of numbers whose product is odd?

How can I write a function that takes an array of integers and returns true if their exists a pair of numbers whose product is odd?
What are the properties of odd integers? And of course, how do you write this function in Java? Also, maybe a short explanation of how you went about formulating an algorithm for the actual implementation.
Yes, this is a function out of a textbook. No, this is not homework—I'm just trying to learn, so please no "do your own homework comments."
An odd number is not evenly divisible by two. All you need to know is are there two odd numbers in the set. Just check to see if each number mod 2 is non-zero. If so it is odd. If you find two odd numbers then you can multiply those and get another odd number.
Note: an odd number multiplied by an even number is always even.
The product of two integers will be odd only if both integers are odd. So, to solve this problem, just scan the array once and see if there are two (or more) odd integers.
EDIT: As others have mentioned, you check to see if a number is odd by using the modulus (%) operator. If N % 2 == 0, then the number is even.
Properties worth thinking about:
Odd numbers are not divisible by 2
Any number multiplied by an even number is even
So you can re-state the question as:
Does the array contain at least two integers that are not divisible by 2?
Which should make things easier.
You can test for evenness (or oddness) by using the modulus.
i % 2 = 0 if i is even; test for that and you can find out if a number is even/odd
A brute force algorithm:
public static boolean hasAtLeastTwoOdds(int[] args) {
int[] target = args; // make defensive copy
int oddsFound;
int numberOddsSought = 2;
for (int i = 0; i < target.length; i++) {
if (target[i] % 2 != 0) {
if (oddsFound== numberOddsSought) {
return true;
}
oddsFound++;
}
}
return false;
}
Thank you for your answers and comments.
I now understand well how to test whether an integer is odd. For example, this method is a neat way of doing this test without using multiplication, modulus, or division operators:
protected boolean isOdd(int i) {
return ( (i&1) == 1);
}
With your help, I now realize that the problem is much simpler than I had expected. Here is the rest of my implementation in Java. Comments and criticism are welcome.
protected boolean isOddProduct(int[] arr) {
int oddCount = 0;
if (arr.length < 2)
throw new IllegalArgumentException();
for (int i = 0; i <= arr.length-1; i++) {
if (isOdd(arr[i]))
oddCount++;
}
return oddCount > 1;
}
I wonder if there exists any other ways to perform this test without using *, % or / operators? Maybe I'll ask this question in a new thread.

Categories