What makes this approach better than this one? - java

The only difference is the nested for loop in the first one is assigned the value of i+1 instead of just +1(second one). Why is the first one considered better than the second one?
int[] nums = { 3, 2, 4 };
int target = 6;
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
int answer = nums[i]+nums[j];
System.out.println(answer);//answer should be value of target
}
}
int[] nums = { 3, 2, 4 };
int target = 6;
for (int i = 0; i < nums.length; i++ ) {
for (int j = 1; j < nums.length; j++) {
int answer = nums[i]+nums[j];
System.out.println(answer);//answer should be value of target
}
}

These two codes are don't seem accomplishing the same to me. however as you said in the comment I'm trying to figure out.
In terms of run time, in the first code, the nested for loop runs nums.length - (i+1) times. Here the best case scenario for nested for loop runs 0 times and for the worst case scenario runsnums.length - 1 times.
int[] nums = { 3, 2, 4 };
int target = 6;
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
int answer = nums[i]+nums[j];
System.out.println(answer);//answer should be value of target
}
}
On the other hand in the 2nd code the nested for loop runs nums.length times. Here the best case and worst case scenario for nested for loop are the same which is runs nums.length times.
int[] nums = { 3, 2, 4 };
int target = 6;
for (int i = 0; i < nums.length; i++ ) {
for (int j = 1; j < nums.length; j++) {
int answer = nums[i]+nums[j];
System.out.println(answer);//answer should be value of target
}
}
Therefore, Based on best and worst case scenario we can say that the first code is more efficient.

The number of iterations in the first code sample is a sum of sequence: n - 1, n - 2, ... 1 that is it's a sum of arithmetic progression of n - 1 elements:
S = (1 + n - 1) * (n - 1) / 2 = n * (n - 1) / 2 = (n^2 - n) / 2
The number of iterations in the second code sample is n * (n - 1) = n^2 - n, that is, it has twice as much iterations as the first one.
However, when estimating complexity (big-O), the constant values such as 2 and expressions of lower order are omitted, thus in both cases O(N) = N^2.

Related

Java arrays produs of even positions

So, for example i have an array: int[] {1,2,3,4,5}. I need to print the product of even positions, 0 position will be considered even, so it will be: 1 * 3 * 5 = 15.
When I am summing an array, I am doing something like this:
int sum = 0;
for (int i = 0; i < arr.length; sum += arr[i++])
and I am receiving the answer correct.
Now, I thought of using the same method for getting the product:
int produs = 1;
for (int i = 0; i < arr.length; produs *= arr[i = i + 2])
Here I always get an error. I don't know why, but if I am doing:
int produs = 1;
for (int i = 0; i < arr.length; i++) {
if ( (i & 1) == 0) {
produs *= arr[i];
}
}
or
int produs = 1;
for (int i = 0; i < arr.length; i = i + 2) {
produs *= arr[i];
}
I am also getting correct answer.
so, my question is why my method with inline for does not work?
int produs = 1;
for (int i = 0; i < arr.length; produs *= arr[i = i + 2])
this one.
If you perform a suffix increment operation, the compiler puts the old value on the stack, e.g.
int[] arr = new int[] { 0, 10, 20, 30 };
int i = 0;
int x = arr[i++]; // x will be 0, i is incremented to 1
On the other hand, if you would use a prefix increment operation, the compiler puts the new value on the stack, e.g.
int[] arr = new int[] { 0, 10, 20, 30 };
int i = 0;
int x = arr[++i]; // x will be 10, i is incremented to 1
Lastly, a variable assignment operation puts the resulting value on the stack, e.g.
int[] arr = new int[] { 0, 10, 20, 30 };
int i = 0;
int x = arr[i = i + 3]; // x will be 30, i is increased by 3
Therefore, if you use arr[i = i + 2] as post-block statement, you actually access the following array elements: 2, 4, 6, yielding an ArrayIndexOutOfBoundsException.
I strongly recommended (also for the sake of readability) that you restructure your algorithm to use the for-block to do the actual calculation and to use the post-block statement to increase the variable i:
for (int i = 0; i < arr.length; i+=2) {
// TODO Calculation
}
You run into an ArrayIndexOutOfBoundsException, because you try to access an element beyond the array boundary. That is because the condition i < arr.length will not be checked when you do produs *= arr[i = i + 2] in the last section of the for-loop.
You can just split up your code inside the increment section, in fact you can chain as many statements in there as you wish, you just have to separate them with a comma ,:
int produs = 1;
for (int i = 0; i < arr.length; produs *= arr[i], i += 2);
The reason you cannot implement a for-loop like this inline is that in the incremental part produs *= arr[i = i + 2] you will have i reaching an index out of the bound of your array because it jumps through 2 steps. Basically in its final iteration, i will reach value of 6 which is out of the indices of your array (the final index of your array is 4) and the part produs *= arr[i = i + 2] will produce an error.
In this case, it is better to use the way that worked for you:
int produs = 1;
for (int i = 0; i < arr.length; i = i + 2) {
produs *= arr[i];
}
You always instantiate your produs with 0.
If you multiply something with zero, than it will be zero.
You have to instantiate it with 1, then should your last example work
int produsOfEven(int[] array) {
int produs = 1;
// step by 2
for (int i = 0; i < array.length; i += 2) {
produs *= array[i];
}
return produs;
}
Edit
To your question, why the last example wont work: As already pointed out in the comments, your condition will be checked to "late".
Let us imagine you have the code for (int i = 0; i < arr.length; produs *= arr[i = i + 2]) and array of length 3. Then this steps will be computed:
Init i with 0.
Check condition i < arr.length, it is true.
Exec body - no body, nothing will happen.
Increase i by running produs *= arr[i = i + 2], i is now 2, produs is changed by array-index 2.
Check condition i < arr.length, it is true.
Exec body - no body, nothing will happen.
Increase i by running produs *= arr[i = i + 2], i is now 4, produs is changed by array-index 4. ArrayIndexOutOfBoundsException was thrown.
You had better use stream
java.util.concurrent.atomic.AtomicInteger index = new java.util.concurrent.atomic.AtomicInteger();
int produs = java.util.Arrays.stream(new int[] {1,2,3,4,5})
.filter(i -> index.getAndIncrement() % 2 == 0).reduce(1, (a, b) -> a * b);

Big O for 3 nested for loops?

public int Loop(int[] array1) {
int result = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1.length; j++) {
for (int k = 1; k < array1.length; k = k * 2) {
result += j * j * array1[k] + array1[i] + array1[j];
}
}
}
return result;
}
I'm trying to find the complexity function that counts the number of arithmetic operations here. I know the complexity class would be O(n^3), but I'm having a bit of trouble counting the steps.
My reasoning so far is that I count the number of arithmetic operations which is 8, so would the complexity function just be 8n^3?
Any guidance in the right direction would be very much appreciated, thank you!
The first loop will run n times, the second loop will run n times however the third loop will run log(n) times (base 2). Since you are multiplying k by two each time the inverse operation would be to take the log. Multiplying we have O(n^2 log(n))
If we can agree that the following is one big step:
result += j * j * array1[k] + array1[i] + array1[j]
then let's call that incrementResult.
How many times is incrementResult called here? (log n)
for (int k = 1; k < array1.length; k = k * 2) {
// incrementResult
}
Lets call that loop3. Then how many times is loop3 called here? (n)
for (int j = 0; j < array1.length; j++) {
// loop 3
}
Let's call that loop2. Then, how many times is loop2 called here? (n)
for (int i = 0; i < array1.length; i++) {
// loop 2
}
Multiply all of those and you'll get your answer :)
That depends on the loops. For instance:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
for (int k = 0; k < 10; k++) {
sum += i * j * k;
}
}
}
has complexity O(1), because the number of iterations does not depend on the input at all.
Or this:
for (int i = 0; i < n*n*n*n*n*n; i++) {
sum += i;
}
is O(n^6), even though there is a single loop.
What really matters is how many iterations each loop makes.
In your case, it is easy to see that each iteration of the innermost loop is O(1). How many iterations are there? How many times do you need to double a number until you reach n? If x is the number of iterations, we'd exit the loop at the first x such that k = 2^x > n. Can you solve this for x?
Each iteration of the second loop will do this, so the cost of the second loop is the number of iterations (which are easier to count this time) times the cost of the inner loop.
And each iteration of the first loop will do this, so the cost of the first loop is the number of iterations (which is also easy to count) times the cost of the second loop.
Overall, the runtime is the product of 3 numbers. Can you find them?

Multiply arrays representing integers (Similar to BigInteger)?

Basically, the integer array (named digits of class BigInteger) is used to represent a single large integer. Up to this point, I have solved how to add-with-carry two of the arrays and also subtract-with-carry, but multiplication is giving me problems. Below is the code I have written:
public BigInteger multiply(BigInteger n) {
int carry = 0;
for(int i = n.digits.length - 1; i >= 0;i--) {
for(int j = this.digits.length - 1; i >= 0; i--) {
int val = (this.digits[i] * n.digits[j]) + carry;
this.digits[i] = val % 10;
carry = val / 10;
}
}//for
return this;
}
This code works as long as the invoking this is larger and the parameter n is a single digit. But as soon as n exceeds 1 digit, the code fails. I am at a loss, and guidance in the right direction would be appreciated.
Replace
for(int j = this.digits.length - 1; i >= 0; i--) {
with
for(int j = this.digits.length - 1; j >= 0; j--) {
You don't want to decrement i while iterating through the inner loop. After you make this correction, you should be good to go.

Java add matrix antidiagonal elements

I want to add a NxN matrix antidiagonal elements using a for loop in a java program.
This code (2 conditions) does not work because it always says when the loop is executed sum2=0.
for (int i=0,j=t-1; i<t && j==0; i++, j--) {
sum2 = sum2 + aNumber[i][j];
}
Instead this one (one condition) works well.
for (int i=0, j=t-1; i<t ; i++, j--) {
sum2 = sum2 + aNumber[i][j];
}
Why does not work the first code?
In your first example the loop ends as soon as j != 0, if t > 1 this means that it will end immediately, making no iterations at all.
Try something like this:
int maxIndex = matrix.length - 1;
int sum = 0;
for (int i = 0; i <= maxIndex; i++) {
sum += matrix[i][maxIndex - i];
}
This relies on the fact that the sum of the indexes of each antidiagonal element is exactly equal to N.

Raising a matrix to the power method JAVA

I am having a really hard time creating a method to raise a matrix to the power. I tried using this
public static int powerMethod(int matrix, int power) {
int temp = matrix ;
for (int i = power; i == 1; i--)
temp = temp * matrix ;
return temp ;
but the return is WAYYY off. Only the first (1,1) matrix element is on point.
I tried using that method in a main like so
// Multiplying matrices
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
for (l = 0; l < row; l++)
{
sum += matrix[i][l] * matrix[l][j] ;
}
matrix[i][j] = sum ;
sum = 0 ;
}
}
// Solving Power of matrix
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++)
matrixFinal[power][i][j] = Tools.powerMethod(matrix[i][j], power) ;
}
Where "power", "row", and "column" is an int that the user enters.
Any ideas how I can do this??
Thanks!!!
You have a lot of issues here.
First, your matrix squaring algorithm has a (common) error. You have:
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
for (l = 0; l < row; l++) {
sum += matrix[i][l] * matrix[l][j] ;
}
matrix[i][j] = sum ;
sum = 0 ;
}
}
However, you need to store the result in a temporary second matrix, because when you do matrix[i][j] = sum, it replaces the value at that position with the output, then later results end up being incorrect. Also I suggest initializing sum to 0 first, since it appears you declare it outside of this loop, and initializing it first protects you against any arbitrary value sum may have before going into the loop. Furthermore, it is not immediately clear what you mean by row and column -- make sure you are iterating over the entire matrix. E.g.:
int temp[][] = new int[matrix.length];
for (i = 0; i < matrix.length; i++) {
temp[i] = new int[matrix[i].length];
for (j = 0; j < matrix[i].length; j++) {
sum = 0 ;
for (l = 0; l < matrix.length; l++) {
sum += matrix[i][l] * matrix[l][j] ;
}
temp[i][j] = sum ;
}
}
// the result is now in 'temp', you could do this if you wanted:
matrix = temp;
Note that matrix.length and matrix[i].length are fairly interchangeable above if the matrix is square (which it must be, in order to be multiplied by itself).
Secondly, your multiplication squares a matrix. This means if you repeatedly apply it, you keep squaring the matrix every time, which means you will only be able to compute powers that are themselves powers of two.
Your third issue is your final bit doesn't make much sense:
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++)
matrixFinal[power][i][j] = Tools.powerMethod(matrix[i][j], power) ;
}
It's not immediately clear what you are trying to do here. The final part seems to be trying to raise individual elements to a certain power. But this is not the same as raising a matrix to a power.
What you need to do is define a proper matrix multiplication method that can multiply two arbitrary matrices, e.g.:
int[][] multiplyMatrices (int[][] a, int[][] b) {
// compute and return a x b, similar to your existing multiplication
// algorithm, and of course taking into account the comments about
// the 'temp' output matrix above
}
Then computing a power becomes straightforward:
int[][] powerMatrix (int[][] a, int p) {
int[][] result = a;
for (int n = 1; n < p; ++ n)
result = multiplyMatrices(result, a);
return result;
}
Why not just use Math.pow?
import java.lang.Math;
Then you just have to do
matrixFinal[power][i][j] = (int) Math.pow(matrix[i][j],power); //might have to cast this to an int

Categories

Resources