Reverting a mutable string implies relocating at least half of the characters (if you do it in-place), so that is O(n) complexity. The code you posted has two loops, confirming it's O(n).
On a more thoeretical note, the entire StringBuilder implementation could be devoted to O(1) inversion, such that you only set a flag and then all the methods honor it by interpreting the array contents either front-to-back or back-to-front. I say "theoretical" because there's no point in increasing the complexity of everything, making it slower as well, just to have O(1) string inversion.
c# - Big O notation for Reverse String - Code Review Stack Exchange
What is the most efficient algorithm for reversing a String in Java? - Stack Overflow
Java String manipulation: Time and Space complexity using StringBuilder - Stack Overflow
What is the time complexity of reversing a string?
Videos
I'm getting ready for an interview and practicing time complexity and I'm ok at recognizing the complexity for the code I've written myself but have a harder time when I throw in methods from the java library.
For example, I read that the method concat was similar to += and that concat time complexity was O(n^2). So if I reverse a string with the code below does that mean my time complexity is O(n^2)? With a space complexity of O(n) since? Where n is the length of the string.
String str="hello"
String s="";
for(int i =str.length()-1; i>=0;i--){
s+=str.substring(i,i+1);
}With this code is the space complexity O(n) and the time complexity O(n)? Where n is the length of the string.
String str="hello";
char[] cArr = str.toCharArray();
int i =0;
int j = cArr.length-1;
char temp;
while(i<j){
temp =cArr[i];
cArr[i]=cArr[j];
cArr[j]=temp;
i++;
j--;
}
str=String.valueOf(cArr);There are a couple of constructs in there that can be improved.
string.Join("", charArray), repeated a lot.stringhas a constructor that takes achar[], which is a lot faster. They are both linear time, which your question seems to focus on, but in terms of actual efficiency the difference is nearly two orders of magnitude in some tests (actual impact of course varies).new Stack(), so.. the old stack, from the .NET 1.1 days? Don't use that one, useStack<T>. Especially if the things you're putting in them are value types, which would have to be boxed in the old non-genericStack.
For ReverseString_ForEachConcat, I don't agree that the time complexity is O(n). At every step, the old string is copied over into the new string, with something concatenated in front of it. So in the second iteration there is 1 copied character, in the third iteration there are 2 copied characters etc. That's a classic O(n²) pattern.
I think we could also argue about whether or not it takes constant space. The many old versions of the string can disappear quickly, but while the concatenation is happening, both the old string and the result of the concatenation need to exist. In the last iteration, that means that while the final result is being made (the size of which doesn't count), there is an other string in play of nearly the same size, so O(n) worth of auxiliary space.
I was going to write this as a comment, but I have too much to talk about. When I first read the question, what was screaming at me is "WHY?!" Why go through such gymnastics? Are you intentionally trying to reinvent-the-wheel? If you are, then please tag the question with that tag.
If you are wanting to learn C#, and equally important, .NET, then I would suggest your focus should be on relying upon the framework.
For a simple Americanized string, where each character in the string is its own entity, you could try something like:
public static string ReverseString(string str)
{
char[] arr2 = str.ToCharArray();
Array.Reverse(arr2);
return new string(arr2);
}
There are also examples here on CR where the reversing is done by only going halfway through the char array. The endpoints are swapped, and then indices are moved inward.
Note the above only works for some strings. If your input string contains certain characters from different cultures, these characters are known as surrogate pairs. You may loosely think of the pair as a composite. For such things, you do not want to reverse the individual characters because it breaks the surrogate relationship. Instead, you would use .NET and look into the StringInfo class (part of System.Globalization). The link provided shows how to honor surrogates.
You say you want to know the most efficient way and you don't want to know some standard built-in way of doing this. Then I say to you: RTSL (read the source, luke):
Check out the source code for AbstractStringBuilder#reverse, which gets called by StringBuilder#reverse. I bet it does some stuff that you would not have considered for a robust reverse operation.
The following does not deal with UTF-16 surrogate pairs.
public static String reverse(String orig)
{
char[] s = orig.toCharArray();
int n = s.length;
int halfLength = n / 2;
for (int i=0; i<halfLength; i++)
{
char temp = s[i];
s[i] = s[n-1-i];
s[n-1-i] = temp;
}
return new String(s);
}