Given a string, that contains special character together with alphabets (‘a’ to ‘z’ and ‘A’ to ‘Z’), reverse the string in a way that special characters are not affected.
Example: Input: str = "a:b!c" Output: str = "c:b!a"
I am using two indexes one to start from the beginning and the other from the end of the array.Swap if they are valid chars and then increment indexes,increment indexes if invalid chars.Any feedback appreciated!
P.S: I am using static methods for convenience.
The Code:
public class ReverseArrayWithoutSpecialChars {
static HashSet<Character> invalidChars = new HashSet<Character>(Arrays.asList(',', '?', ':','!','$'));
public static char[] reverseSkippingSpecialChars(char[] charArray) {
int l = 0;
int r = charArray.length - 1;
for (int i = 0; i < charArray.length; i++) {
if (r <= l) {
break;
}
if (!isInvalidChar(charArray[l]) && !isInvalidChar(charArray[r])) {
charArray = swapChars(charArray, l, r);
l++;
r--;
} else if (isInvalidChar(charArray[l])) {
l++;
} else if (isInvalidChar(charArray[r])) {
r--;
}
}
return charArray;
}
public static char[] swapChars(char[] charArray, int index1, int index2) {
char temp = charArray[index1];
charArray[index1] = charArray[index2];
charArray[index2] = temp;
return charArray;
}
public static boolean isInvalidChar(char character) {
return invalidChars.contains(character);
}
public static void main(String args[]) {
char[] charArray = new char[]{'a', 'b', 'c', 'd', '?', 'f', 's', ':', 'w'};
System.out.println(reverseSkippingSpecialChars(charArray));
}
}
1 Answer 1
Class fields
static HashSet<Character> invalidChars = new HashSet<Character>(Arrays.asList(',', '?', ':','!','$'));
You might as well go ahead and make this final
as well.
public static final Set<Character> invalidChars = new HashSet<>(Arrays.asList(',', '?', ':', '!', '$'));
As a final
variable, it's clear that it won't change.
We should probably specify a visibility. Unless it's a secret, we should go ahead and make it public
. Since it's final
, no one can change it.
It is better to type to the interface than the implementation. This allows us to change the implementation without changing the type. And it forces us to limit ourselves to the operations available in the interface.
In newer versions of Java, you don't need to say Character
twice. The compiler will figure out the type on the second one.
Eliminate unnecessary variables
int l = 0; int r = charArray.length - 1; for (int i = 0; i < charArray.length; i++) { if (r <= l) { break; }
You can write this either
for (int l = 0, r = charArray.length - 1; l < r; ) {
or
int l = 0;
int r = charArray.length - 1;
while (l < r) {
You don't need the extra i
variable. Nor do you need to do the l < r
check separately.
It's up to you if you use a for
or a while
. Either will work. The for
is a bit more compact, but you have to leave the update section blank. Either will be shorter.
Not really invalid
if (!isInvalidChar(charArray[l]) && !isInvalidChar(charArray[r])) { charArray = swapChars(charArray, l, r); l++; r--; } else if (isInvalidChar(charArray[l])) { l++; } else if (isInvalidChar(charArray[r])) { r--; }
It's not that the characters are invalid. They are expected and you want to preserve them. It's that the character are special and treated different. Consider
if (isSpecialChar(charArray[l])) {
l++;
} else if (isSpecialChar(charArray[r])) {
r--;
} else {
// neither is a special character
swapChars(charArray, l, r);
l++;
r--;
}
You use the terminology special elsewhere, so why not here?
I also like that this emphasizes the positive.
Since we already know that neither character is a special character, we don't have to check again.
The swapChars
method modifies the charArray
in place. We don't have to return
it and assign.
Generating a character array
char[] charArray = new char[]{'a', 'b', 'c', 'd', '?', 'f', 's', ':', 'w'};
If you want to type less, consider
char[] charArray = {'a', 'b', 'c', 'd', '?', 'f', 's', ':', 'w'};
or
char[] charArray = "abcd?fs:w".toCharArray();
No big deal, but why type more than necessary?