You're right. Two algorithms are equivalent in Big O notation if one of them takes longer ("A takes 5 minutes more than B") or several ("A takes 5 times longer than B") or both ("A takes 2 times B plus an additional 30 milliseconds ") for all input sizes.
Here is an example that uses FUNDAMENTALLY another algorithm to solve a similar problem. Firstly, a slower version, which is very similar to your original example:
boolean arraysHaveAMatch = false; for (int i = 0; i < arr1.length(); i++) { for (int j = i; j < arr2.length(); j++) { if (arr1[i] == arr2[j]) { arraysHaveAMatch = true; } } }
This has O (n ^ 2) behavior, just like your original (it even uses the same shortcut that you opened to run index j from index i instead of 0). Now this is a different approach:
boolean arraysHaveAMatch = false; Set set = new HashSet<Integer>(); for (int i = 0; i < arr1.length(); i++) { set.add(arr1[i]); } for (int j = 0; j < arr2.length(); j++) { if (set.contains(arr2[j])) { arraysHaveAMatch = true; } }
Now, if you try to run them, you will probably find that the first version launches FASTER. At least if you try to use arrays of length 10. Because the second version must deal with the creation of the HashSet object and all its internal data structures and because it must calculate the hash code for each integer. HOWEVER, if you try it with arrays of 10,000,000 in length, you will find a TOTALLY different story. The first version should examine about 50,000,000,000,000 pairs of numbers (about (N * N) / 2); the second version should perform hash function calculations on about 20,000,000 numbers (about 2 * N). In this case, you definitely need the second version!
The main idea of Big O computing is that (1) it is easy to calculate (you don’t need to worry about details like the speed of your processor or what kind of L2 cache it has), and (2) who cares about small problems ... they are fast enough anyway: these are BIG problems that will kill you! This is not always the case (sometimes it matters what your cache is, and sometimes it matters how well everything works on small datasets), but they are close enough to the truth, often enough, so Big O is useful.