Hi how come swapping technique(my code) suffers Timeout where as circular array
{(i+number of rotation)%length} implementation does not?
a is an int[].
for (int i = 0; i < numberofrotation; i++) {
for (int j = 0; j < a.length-1; j++) {
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
return a;
(i+number of rotation)%length is to advance by number of rotations and wrap around to form circular array.
With modulo number of rotations are reduced to less than or equals to length of array, hence faster execution
To give you some idea...
Taking your approach of swapping array values,
if an array of length 10 is swapped by n times where n is a multiple of 10 ,
means n mod 10 = 0, than result is original array.
If value of n is not a multiple of 10 than you will see array order change in array values.
you can get the result either by rotating n times, or same result can be achieved by rotating n mod 10 times
So if n = 25 than swapping array by 25 is equivalent to swapping array 5 times
25 mod 10 = 5
similarly if n=13 , than swapping array by 13 time will have same result of swapping array 3 times
13 mod 10 = 3
Even if number of rotation is Integer.MAX_VALUE and length of array to rotate is 100,
number of rotations can be reduced to Integer.MAX_VALUE%100 which is 47.
Related
I am new to Java so I don't really understand this yet, I just want to know how does this code work and how the count increase. Why is there a loop inside a loop?
(This is not my own code it is something i am studying.)
Random r = new Random();
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++) {
int n = r.nextInt(3);
Gridbox[i][j] = n;
if (n == 0)
{
count++;
}
}
r.nextInt(3) results in a uniform random number between 0 (inclusive) and 3 (exclusive). Why? Because the docs say so; javadoc is a great place to start when trying to figure out what things do.
In other words, 33% of the time that returns 0, 33% of the time it returns 1, and 33% of the time it returns 2, randomly determined.
In other words, 33% of the time (on average), n would be 0, and count would be increased.
All this code does is loop 5 times (first 'for'), and per outer loop, loop 5 times (for a total of 5*5 = 25 times a random number is generated).
Gridbox is some sort of 5 by 5 array; the randomly generated number is placed in this grid, and count is incremented 33% of the time.
The count increases here, by one each time this line is executed:
count++;
Look up the increment operator ++ to understand.
There is loop inside a loop, a socalled pair of nested loops, in order to cover all possible combinations of possible is and js, i.e. to cover all of the 2D range.
If you want to learn a programming language I recommend to first read a book and maybe follow tutorials. Reading existing code is for later, though not a bad idea.
I added a comment to every line of code; and tried to explain here.
You're creating a gridbox of size i x j. In your code's case you are hardcoding i and j to a size of 5(using the for loops both sized 5)
r.nextInt(3) results in a uniform random number between 0 (inclusive) and 3 (exclusive). So you are assigning each value inside the gridbox a random value between 0 and 3.
Whenever you do the assignment, if the value is 0 increment the count.
//random class that allows generation of random values
Random r = new Random();
//for loop of size 5, start at 0 and go through it 5 times. **i** is the first param of gridbox
for (int i = 0; i < 5; i++)
{
//for loop of size 5, start at 0 and go through it 5 times. **j** is the second param of Gridbox
for (int j = 0; j < 5; j++) {
// assign random integer value between 0 and 3 to field n.
int n = r.nextInt(3);
// push n into GridBox. this might be a typo. In java Capital indicates its a class not a instance of the class
Gridbox[i][j] = n;
// if **n is equal 0 increment count.
if (n == 0)
{
count++;
}
}
I imagine you need to do a instantiation
//this needs to be properly instantiated, to right size.
Gridbox gridbox = new Gridbox();
gridbox[i][j] = n
Since this 2 loops, iterate at different amount, whats can be the time complexity
int middleindex = items.length/2;
int index = 0;
while(index < middleindex){
System.out.println(items[index]);
index++;
}
for(int i = 0 ; i < 100 ; i++){
System.out.println("Hi");
}
The first loop will take a time related to the number of items:
if you have n items, it will take a time t.
if you have 10 * n items, it will take 10 * t
So you can see that the computation time is linearly related to the number of items. It is O(n).
The second loop isn't related to the number of items, it will always run in constant time. It is O(1).
My code is timing out as it is inefficient. Program takes in a line of n integers. Each consecutive pair of integers represents a single point (x, y)
this is an example of input :
-5 -10 20 25 30 2 -1 -40
Output:
java.awt.Point[x=-5,y=-10]
java.awt.Point[x=-1,y=-40]
java.awt.Point[x=20,y=25]
java.awt.Point[x=30,y=2]
4
I have the code to sort all the points. They are sorted from smallest to biggest. Where "x" values are equal, I then check the y value.
The PROBLEM is this: I need to count how many times a point is bigger than every other point (both x and y). So in the above example, the answer is 4.
The fourth point is bigger than the first and second point.
The third point is bigger than the first and second.
Which results in 4.
If points are equal, also increase the counter.
For really really longer line of integers, my program times out (killed). I can't provide the input here as it is way too long. How else can I improve the complexity?
public void calculateDomination(){
int counter =0;
int sizeOfList = this.coordinateList.size();
for(int i = 0; i < sizeOfList ; i++){
for(int j = i+1; j < sizeOfList ; j++){
if(((this.coordinateList.get(i).x) < (this.coordinateList.get(j).x)) && ((this.coordinateList.get(i).y) < (this.coordinateList.get(j).y)) ){
counter++;
}
else if(((this.coordinateList.get(i).x) == (this.coordinateList.get(j).x)) && ((this.coordinateList.get(i).y) == (this.coordinateList.get(j).y)) ){
counter++;
}
}
}
System.out.println(counter);
}
The first idea I posted, now removed, would not actually work. The one that does work:
Use an incremental sorting/counting of encountered y values:
As you go through the list, maintain a TreeMultiset of all the y values encountered so far. At each point, check the size() of the headMultiset() of nodes before the current y value. Since only values from points with lower x values will have been added to it yet, that will give you the current point's count.
I think all involved operations of TreeMultiset are O(log(n)), so this will drop your algorithm from O(n^2) to O(n * log(n)).
I got a pseudocode:
Input: Array A with n (= length) >= 2
Output: x
x = 0;
for i = 1 to n do
for j = i+1 to n do
if x < |A[i] - A[j]| then
x = |A[i] - A[j]|;
end if
end for
end for
return x;
I have converted that to a real code to see better what it does:
public class Test
{
public static void main (String[] args)
{
int A[] = {1,2,3,4,5,6,7,8,9};
int x = 0;
for (int i = 1; i < A.length; i++)
{
for (int j = i + 1; j < A.length; j++)
{
if (x < Math.abs(A[i] - A[j]))
{
x = Math.abs(A[i] - A[j]);
}
}
}
System.out.println(x);
}
}
The output was 7 with the array in the code.
I have used another array (1 to 20) and the putput was 18.
Array 1-30, the output was 28.
The pattern seems clear, the algorithm gives you the antepenultimate / third from last array value. Or am I wrong?
I think the pseudo code tries to find the greater of the difference between any 2 elements within an array.
Your real code however, starts from 1 instead of 0 and therefore excludes the first element within this array.
I think pseudocode is trying to find the greatest difference between two numbers in an array. It should be the difference between the minimum and maximum value of the array.
I personally think this is a really poor algorithm since it is doing this task in O(n^2). You can find the min and maximum value of an array in O(n). and take the difference between those numbers and result will be the same. check the pseudocode
Input: Array A with n (= length) >= 2
min=A[0];max = A[0];
for i = 1 to n do
if min > A[i] then
min = A[i];
end if
if max < A[i] then
max = A[i]
end if
end for
return (max-min);
The code gives the biggest difference between any two elements in the array.
There are 2 nested loops, each running over each element of the array. The second loop starts at the element after the first loop's element, so that each possible pair is considered only once.
The variable x is the current maximum, initialized to 0. If x is less than the absolute value of the current pair's difference, then we have a new maximum and it is stored.
However, because you directly copied the pseudocode's starting index of 1, you are inadvertently skipping the first element of the array, with index 0. So your Java code is giving you the maximum difference without considering the first element.
If you have an array of values between 1 and n, you are skipping the 1 (in index 0) and the returned value is n - 2, which happens to be the third-to-last value in the array. If you had shuffled the values in the array as a different test case, then you would see that the returned value would have changed to n - 1 as now both 1 and n would be considered (as long as n itself wasn't in the first position).
In any case, you would need to set the index of the first element to 0 so that the first element is considered. Then {1,2,3,4,5,6,7,8,9} would yield 8 (or any other order of those same elements).
Assuming all positive integers, the algorithm in a nutshell finds the difference between the maximum and the minimum value in the array. However, it will not work correctly unless you initialize i to 0 in the for loop.
for (int i = 0; i < A.length; i++)
I have a large array. I have some Java code for identifying indices for start and end points for a subset/slice of that large array. The only information items that I need to retrieve from the selected subsection of the array are the indices and values of the local maximum and minimum. What is the fastest (and least memory intensive) way that I can find a max and min within the specified range?
Here is a start of what I need in terms of code:
// Step One: declare new array and populate it
pts = new double[5000];
for (int i = 0; i < 5000; i++){ pts[i] = (value assigned by extraneous process);}
// Step Two: slice out section between indices 3600 and 3750
// what code do I write here?
// Step Three: find max value in the sliced section and return its index
// what code to I write here?
Just iterate over the desired range and record maximum and minimum seen values:
double max = Double.NEGATIVE_INFINITY;
double min = Double.POSITIVE_INFINITY;
int minIndex = -1;
int maxIndex = -1;
for(int k = 3600; k < 3750; k++){
if(max < pts[k]){
max = pts[k];
maxIndex = k;
}else if(min > pts[k]){
min = pts[k];
minIndex = k;
}
}
If it's not necessary to create a copy of the array for your slice, you can essentially do steps 2 and 3 in one fell swoop:
double max = pts[3600]; //the value of the first element in the slice
int maxIndex = 3600; //keep track of the index as you go. Assume at first
//that it is the first index of the slice
for(int i=3601; i<=3750; i++){
if(pts[i] > max){ //you have encountered a larger element. Update the maxes
max = pts[i];
maxIndex = i;
}
}
System.out.println("The max is " + max + " and occurred at index " + maxIndex);
(sorry for any syntax errors, I've been messing around with Scala and the grammar is a little different)
Have a loop that goes over the selected subsection once.
In the loop, adjust the values of four variables maxValue, maxIndex, minValue, minIndex as you find new maxima or minima.
After the loop, you will have the maximum and minimum and their positions.
No extra memory needed, linear performance (just one pass over the selected part of the array).
If you're going to do this a lot, you could increase performance by keeping track of the maxima / minima at different scales.
For instance if you keep a list for every 20 rows, and you want to check the range 55 - 184, you'd only need to check 5 values (55-59), then 6 values from 60-179, then 4 values from 180 - 184, so that's 15 checks rather than 130, a 20x speed increase.
Of course, you'd need to mark your buckets as changed when the array changes and periodically update them.