I've been doing some reading on time complexity, and I've got the basics covered. To reinforce the concept, I took a look at an answer I recently gave here on SO. The question is now closed, for reason, but that's not the point. I can't figure out what the complexity of my answer is, and the question was closed before I could get any useful feedback.
The task was to find the first unique character in a string. My answer was something simple:
public String firstLonelyChar(String input)
{
while(input.length() > 0)
{
int curLength = input.length();
String first = String.valueOf(input.charAt(0));
input = input.replaceAll(first, "");
if(input.length() == curLength - 1)
return first;
}
return null;
}
My first thought was that since it looks at each character, then looks at each again during replaceAll(), it would be O(n^2).
However, it got me to thinking about the way it actually works. For each character examined, it then removes all instances of that character in the string. So n is constantly shrinking. How does that factor into it? Does that make it O(log n), or is there something I'm not seeing?
What I'm asking:
What is the time complexity of the algorithm as written, and why?
What I'm not asking:
I'm not looking for suggestions to improve it. I get that there are probably better ways to do this. I'm trying to understand the concept of time complexity better, not find the best solution.
length()have to count every character in the string each time, or is the length stored separately so it can be returned without a linear scan? 2) Iflength()is linear, do we at least remember the result for subsequent calls? 3) What kind of memory management is used by the class - is erasing a character a simple constant-time operation, or does it require a linear re-copy of the remainder of the string? 4) When, if ever, do cumulative erasures cause reallocation and copy? And so on...replaceAllmust scan the entire string, since that is the "standard" implementation, unless otherwise specified.replaceAllcertainly must scan the entire string to look for matches, but the question was more for the actual erasure and how it's handled - I can think of three equally effective methods to writereplaceAlloff the top of my head, but they're not equivalent in efficiency (copy non-erased characters to temp string and copy back, or shift the string tail left on each erasure, or simply mark an erased character in some way to indicate "no character here")...input = /* ... */) do any of your three methods have run-time complexity other linear?