This question already has answers here:
Big O, how do you calculate/approximate it?
(24 answers)
Closed 3 years ago.
I'm struggling with calculating time complexity in this code.
Only capable of simple code at the moment...
just want to try with complex one!
public static int PATHWAY = 0;
public static int WALL = 1;
public static int MARKED = 2;
public static boolean find(int x, int y) {
if(x == 7 && y == 7) return true;
maze[x][y] = MARKED;
if(x != 0 && maze[x-1][y] == PATHWAY && find(x-1, y)) return true;
if(y != 0 && maze[x][y-1] == PATHWAY && find(x, y-1)) return true;
if(x != 7 && maze[x+1][y] == PATHWAY && find(x+1, y)) return true;
if(y != 7 && maze[x][y+1] == PATHWAY && find(x, y+1)) return true;
return false;
}
Well, in each recursive call you visit a single cell in your 2D array.
Since you mark the visited cells, you can't visit the same cell twice.
Hence the total recursive calls is bound by the length of the 2D array.
Apart from the recursive call, you perform a constant amount of work in each execution of the find() method.
Therefore the time complexity is O(N*M) if N is the number of rows and M the number of columns of the 2D array.
Of course, based on your stopping condition of if(x == 7 && y == 7) return true;, it looks like the dimensions of your 2D array are 8x8, which can be seen as a constant. That would make the running time O(1).
O(N*M) is the complexity for a general input array.
Basically you can calculate assignments and operations.
Have a
int assignments = 0;
int operations = 0;
which you will increment every time you do one.
Other way in doing this is to monitor the time, but it's not the most reliable one.
You can also calculate/approximate Big-O, check Big O, how do you calculate/approximate it?
Well it's not that hard, it actually uses DFS in order to find a path. the order of DFS is O(V+E), where V is the number of vertices and E is the number of edges.
In this case you are using a adjacency matrix to represent your graph. so in worst case the time complexity would be O(M*N), where M is the number of rows and N is the number of columns.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I am writing a method that takes in two numbers and will return true if they are both even or both odd... and will return false if only one is odd and one is even.
It needs to return a boolean statement, but it is not working.. Any help is appreciated! Thanks...
public static boolean compareEvenOdd(int x, int y) {
if((x % 2 ==0) && ( y% 2==0))||((x%2 != 0) && (y%2 != 0)){
return true;
} else
return false;
}
You can do the following (possibly the shortest version):
public static boolean compareEvenOdd(int x, int y) {
return ((x + y) % 2) == 0;
}
The sum of two odd numbers and the sum of two even numbers is even, the sum of one odd and one even number is odd. So you add the numbers and check if the solution is dividable by 2.
This is a really good opportunity to use a bitwise operator. You can use the binary AND (&) operator with the number 1 to reduce an integer to just its last binary digit. This last digit is always 0 for an even number and 1 for an odd number. If your two numbers have the same last binary digit, then they have the same parity - that is, they're both even or both odd. So I would write the method like this.
public boolean sameParity(int x, int y) {
return (x & 1) == (y & 1);
}
Note that the parentheses are important, because the usual Java order of operations puts == above &.
Seems you are missing an additional pair of parentheses around the condition in the if-statement.
This works for me:
public static boolean compareEvenOdd(int x, int y) {
if (((x % 2 ==0) && ( y% 2==0))||((x%2 != 0) && (y%2 != 0))){
return true;
} else
return false;
}
if this is not to your liking, yould you further specify what is not working? Is it throwing errors as you run it, is the output wrong,...?
Explication :
x and y are odd : x+y are even
x and y are even : x+y are even
x is odd and y is odd : x+y are odd
x is even and x is even : x+y are odd
public static boolean compareEvenOdd(int x, int y) {
return (x+y)%2==0
}
An if-statement always has the form if (...) with its own parentheses around the condition. Hence you missing just that.
So (with unneeded braces removed):
public static boolean compareEvenOdd(int x, int y) {
if ((x % 2 == 0 && y % 2 == 0)
|| (x%2 != 0 && y % 2 != 0)) {
return true;
} else
return false;
}
And as shown in the other answers this should be simplified,
as if+return boolean means using boolean redundantly, not to the fullest (like == true):
return (x % 2 == 0 && y % 2 == 0)
|| (x % 2 != 0 && y % 2 != 0);
return (x % 2) == (y % 2);
return (x - y) % 2 == 0;
I have a big list of coordinates (this form):
if(x == 1055 && y == 63 && z == 1117)
return blackwood;
if(x == 1053 && y == 63 && z == 1117)
return blackwood;
if(x == 1049 && y == 64 && z == 1113)
return blackwood;
if(x == 1054 && y == 63 && z == 1112)
return blackwood;
if(x == 1058 && y == 63 && z == 1112)
return blackwood;
if(x == 1062 && y == 64 && z == 1117)
return blackwood;
if(x == 1050 && y == 64 && z == 1117)
return blackwood;
if(x == 1062 && y == 64 && z == 1118)
return glass;
if(x == 1050 && y == 64 && z == 1118)
return andesite;
(Much longer than that)
But, when I call the method that execute these instructions, I have a lag (Not very long, but enough to have a freeze impression in-game).
So, my question is, how can I optimize this?
I was thinking about stocking these in a HashMap and use HashMap.get(key), but, does HashMap.get(key) iterate the list to find it out?
You could indeed use a Map with as key a custom class that uses as component value these 3 data : x, y and z.
With a fair implementation of the hashCode() method, it should be a constant time [O(1)] or very close to.
If you have to recreate the map as often as you need to request it, using a map could be helpless as from one side you could loose what you gain from another side.
So, create this custom class and override hashCode() and equals() by taking these 3 fields into consideration :
public class Coordinate {
private int x;
private int y;
private int z;
public Coordinate(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
result = prime * result + z;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof Coordinate))
return false;
Coordinate other = (Coordinate) obj;
if (x == other.x && y == other.y && z == other.z)
return true;
return false;
}
}
Then you could initialize the map with expected key-values :
Map<Coordinate, MyValue> mapValuesByCoord = new HashMap<>();
mapValuesByCoord.put(new Coordinate(1055,63,1117), blackwood);
mapValuesByCoord.put(new Coordinate(1053,63,1117), blackwood);
mapValuesByCoord.put(new Coordinate(1062, 64, 1118), glass);
...
And use the map in this way :
MyValue value = mapValuesByCoord.get(new Coordinate(1055,63,1117));
There's an issue here with the common use of the word "map", as in a piece of paper showing a miniature representation of a piece of land, versus the programmer or mathematician's use of "map", in which values are associated with other values.
If pretty much every 3D coordinate has a corresponding return value, you would be better off having a direct lookup table. You could do this with a 3D array, i.e. an array-of-arrays-of-arrays:
Rock[][][] rockMap = ... // Google for guidance on initialising a 3D array
...
rockMap[1054][63][1112] = blackwood;
// etc.
Here "rockMap" is closer to the common use of the word "map". If you drew that 3D array, it would be your "world map".
Then your lookup is:
return rockMap[x][y][z];
Alternatively you could use a 1D array and calculate an index from x, y, z:
Rock[] rockMap = new Rock[SIZE_X * SIZE_Y * SIZE_Z];
rockMap[1054 * SIZE_Y * SIZE_Z + 63 * SIZE_Z + 1112] = blackwood;
Lookup is similar to assignment:
return rockMap[x * SIZE_Y * SIZE_Z + y * SIZE_Z + z];
If you don't have a rock for every coordinate, this approach would still work (you'd just have a null, or some other absence marker, in all the empty slots). But it would be a bit wasteful of space.
In this case it could be more efficient to create a Coordinate type, and construct a Map<Coordinate>.
Map<Coordinate> rockMap = ...;
rockMap.put(new Coordinate(x,y,z), blackwood);
...
return rockMap.get(new Coordinate(x,y,z));
You should do your own tests to find out what type of Map works best in your program -- HashMap? TreeMap? Test them.
For these to work, Coordinate needs to implement certain methods -- check the Javadoc and make sure it does.
HashMap rarely iterates to get an element from its structure. Proper implementations iterate so rarely that people usually don't bother mentioning that part exists. Hence the O(1) complexity.
Imagine a table of your elements (every element has a key). Ideally HashMap will put every one of your elements in a unique row (so only 1 element per row). When given a key to get an element, HashMap will calculate a hash (int) of the key and find out in which row is its appropriate value located. Multiple elements in one row can occur because sometimes two different keys can have same hashes and then you iterate that row to find your element.
I think you could use a HashMap on your problem to speed it up a bit (where x, y and z should be unique keys).
I would create blackwood, glass and andesite object that have check(x, y, z) method.
Edit:
Maybe I should have also added that to make it more efficient you can implement blackwood.check(x, y, z) like this:
public boolean check(int x, int y, int z){
if ( y == 63 || y == 64){
if (z == 1117 || z == 1113 || z == 1112){
if (x == 1055 || x == 1053 || x == 1049 || x = 1054 ||
x == 1058 || x == 1062 || x == 1050){
return true;
}
}
}
return false;
}
What you will gain from this:
1) The logic for each type is encapsulated into separate classes and you wont have one huge method with long "ifs". And it will be easy to add a new type.
2) By moving the "y" check to top you will do a quick exit if its not 63 or 64. Same applies to z. Since "or" check in Java will not check the rest you will buy some performance by not checking all "x" values if x is 1055 for example.
3) Using Map or Set approach you have to create X, Y, Z wrapper key object on each call to your method. With the method being called very frequently you might have issues with garbage collector not being able to clean them up fast enough.
This question already has answers here:
Performance: greater / smaller than vs not equal to
(7 answers)
Closed 6 years ago.
I was implementing a snippet on Leetcode and my initial loop ran like this:
//n and x are an integer and a double respectively
long N = Math.abs((long)n);
double result = 1;
while(N != 0){
if((N & 1) == 1){
result *= x;
}
N = N >> 1;
x *= x;
}
The whole code took 2ms to run. I then changed N != 0 to N > 0 and the code took 1ms to run. Why was there a jump in runtime due to this change? In other words, how does Java implement x != y and x > y?
Probably because when jvm checks for N > 0 it looks just for byte that represents sign and when jvm checks for N != 0 it needs to go through all bytes in the variable.
The question is : a man is looking for a target(which is marked as 9) in a 2D array, where 0 represents walls and 1 represents roads. The method should find if the man can find the target or not.
I came up with the solution using DFS easily, but got stuck when trying to find out the time and space complexity of my code.
public boolean find(int[][] grid) {
if(grid == null || grid.length == 0 || grid[0].length == 0 || grid[0][0] == 0) return 0;
return helper(grid,0,0);
}
private boolean helper(int[][] grid,int x, int y) {
if(x >= 0 && x < grid.length && y >= 0 && y < grid[0].length) {
if(grid[x][y] == 0) return false;
else if(grid[x][y] == 9) return true;
else if(grid[x][y] == 1) {
grid[x][y]=2;
return helper(grid,x,y-1) || helper(grid,x+1,y) || helper(grid,x,y+1) || helper(grid,x-1,y);
}
else return false;
}
else return false;
}
I think the time and space complexity is O(mn), but I am not sure.
Generally speaking, DFS has a time complexity of O(m + n) and a space complexity of O(n), where n is the number of locations you can be in and m is the total number of connections between locations (if you're familiar with graph theory, n is the number of nodes and m is the number of edges). In your case, if you have a grid whose size is w × h, then n = wh (there's one place you can be for each grid location) and m ≤ 4wh (since each location is adjacent to at most four other locations). This means that the runtime will be O(wh) and the space complexity will be O(wh) as well.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm not finding any fault with my program. Please point out my mistake and help me.
Code is written below:
class largest
{
public static void main(String...args)
{
double n,i,f=1.0;
n=600851475143L;
largest ob= new largest();
for(i=n/4;i<n/2;i++)
{
if(n%i==0)
{
if(ob.isprime(i) == 1)
f=i;
}
}
System.out.println(f);
}
int isprime(double k)
{
int s,i=2,flag=0;
while(i<k && flag==0)
{
if(k%i==0)
flag=1;
}
if(flag==0)
return 1;
else
return 0;
}
}
Your function isprime is in most cases an endless loop. It never increments i in the loop.
Every time you write a loop, you should think about the so called loop variant. This is numerical property of the loop, that is both:
A positive integer in each loop run
Decreasing during successive iterations of the loop
If you cannot think about such a property, you are in big trouble, because you have very likely an endless loop.
In your example, that property should be the number whose prime factor you want minus the current prime factor candidate you are checking.
In your current code, if you calculate the loop variant, you will get a positive integer (good), but it will not decrease (bad). As an consequence, you will wait forever, because you have an endless loop.
While other answers show nice solutions to make your code more efficient, this won't help you very much: an efficient endless loop still won't give you any result.
Your code is far too slow, that's why it takes so much time to execute and doesn't return any output (apparently). You should speed up your isPrime test using the following trick : if n is not a prime, it can be written as n = p x q where p <= sqrt(n) and q > p. Then, you can stop your loop at sqrt(n) since you are able to tell that n is not a prime if there is no integer p <= sqrt(n) verifying this property.
The following code uses that remark but also another property : a integer can always be written as 6*p + q where p and q are integers and q < 6. For all p, 6*p + 2 and 6*p + 4 are divisible by 2 and 6*p + 3 is divisible by 3 so for all n = 6*p + q, if n is not divisible by 2 nor by 3, then n has the form 6*p + 1 of 6*p + 5 (or 6*p - 1, which is equivalent).
public static boolean isPrime(int n) {
if (n == 2 || n == 3)
return true;
if(n <= 1 || n % 2 == 0 || n % 3 == 0)
return false;
int x = (int) Math.sqrt(n);
for(int i=1 ; (6*i-1) <= x ; i++)
if(n % (6*i-1) == 0 || n % (6*i+1) == 0)
return false;
return true;
}
Edit :
Plus, as stefan.schwetschke observed, you are not incrementing the index of your loop. In this case you should use a for loop since you now exactly the bounds of the index of the loop.
This is not a "code" answer (none of the other answers will provide a solution in a reasonable amount of time , even when correcting your brute force original code).
You may want to explore prime factorization algorithms, with Pollard-Strassen algorithm (or Rho Pollard algorithm).
Some research links include:
Wolfram Research http://mathworld.wolfram.com/PollardRhoFactorizationMethod.html
Colorado State University lecture http://www.cs.colorado.edu/~srirams/classes/doku.php/pollard_rho_tutorial
and here https://math.stackexchange.com/questions/185524/pollard-strassen-algorithm
(for mathematics on stackexchange.