It is easy to find O(n^2) algorithm, you simply have to compare every single character with other characters and increment the count, then return the most repeated character.
It appears the time complexity to be O(n^2) since there are two for loops.
There are two loops, but each does not loop n times. The outer loop happens a constant number of times. The inner loop text.length() times. So it is O(n).
Just because there's a loop inside another doesn't mean that the time complexity is O(n^2). The time complexity of this algorithm is O(1):
1 2 3 4
for (int i = 0; i < 1000000; i++){
for (int j = 0; j < 1000000; j++){
}
}
The inner loop runs for text.length() iterations, and the outer loop runs for k iterations. In total, that's k*text.length(), or just k*n. Since big O notation compares the asymptotic behavior of algorithms, constant factors are ignored, therefore the time complexity is just O(n).
These two algorithms have the same time complexity:
for (int i = 0; i < n; i++);
1 2
for (int i = 0; i < n; i++)
for (int j = 0; j < 1000000; j++);
Ok, but the outer for loop is running the ASCII character and symbols (we can consider this set of ASCII characters and symbols to be of a certain size n). That indicates for every iteration of outer loop we are comparing the second loop text.length()-1 times, so I think it is O(n^2).
Ok, but the outer for loop is running the ASCII character and symbols.
we can consider this set of ASCII characters and symbols to be of a certain size n
About 95 of them. Not n. In this case, n is the variable size of the string to be examined.
So the outer loop will run 95 times. Not n. Not anyhting to do with length of the text. A fixed amount.
So we will loop 95*n times in total, which is O(n).
I don't know why my edited response went lower, but I think I am understanding what you mean.
@helois
I believe you mean every loop is running on its own, so that is O(n). Can you explain to me how would the algorithm in the question would become O(n^2)? What conditions make the time complexity to change?
@Repeater, yeah that is true, some running times are like 3n^2 + 2n + 5, and we only take the greatest leading variable so n^2, and we ignore constants. I understand what you mean now :)
I just started studying about running times and efficiency, so I'm getting there.
#include <iostream>
#include <string>
#include <unordered_map>
int main()
{
std::string s;
getline( std::cin, s );
std::unordered_map <char, std::size_t> histogram;
for (char c : s) histogram[ c ] += 1; // O(n) × O(1)
std::size_t count = 0;
for (auto p : histogram) // O(n)
if (p.second > count) { count = p.second; s = p.first; }
elseif (p.second == count) { s += p.first; }
if (s.size() != 1) std::cout << "No one character most common.\n";
else std::cout << "Most common character is '" << s << "'.\n";
}
It is easy to find O(n^2) algorithm, you simply have to compare every single character with other characters and increment the count, then return the most repeated character.
That isn't O(n^2) because the second search isn't dependent on n, it's dependent on the number of characters in your alphabet, so it's O(n).
int occurenceTable[0xff] = {0}; //O(1) space complexity
for(char c: someString) //O(n) loop
++occurenceTable[int(c)];
char mostOccurent;
int max = 0;
for(unsigned i = 0u; i < 0xff; ++i) //find max in O(1)
{
if(occurenceTable[i] > max)
{
max = occurenceTable[i];
mostOccurent = char(i);
}
}