Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters.
The input string does not contain leading or trailing spaces and the words are always separated by a single space.
For example,
Given s = “the sky is blue”,
return “blue is sky the”.
Could you do it in-place without allocating extra space?
Java Solution
public void reverseWords(char[] s) { int i=0; for(int j=0; j<s.length; j++){ if(s[j]==' '){ reverse(s, i, j-1); i=j+1; } } reverse(s, i, s.length-1); reverse(s, 0, s.length-1); } public void reverse(char[] s, int i, int j){ while(i<j){ char temp = s[i]; s[i]=s[j]; s[j]=temp; i++; j--; } } |
static String reverseWords(String input) {
String s = Arrays.stream(input.split(" "))
.sorted(Comparator.naturalOrder())
.collect(Collectors.joining(" "));
return s;
}
The solution can definitely be simplified with nested loop and 4 pointers. e.g. i and j for nested loop, start and end for each word to reverse, i for string end-to-end, j for words separator. Swap chars between start and end until floor(stat/end) for each word. Reset start and end according I and J to swap next word.
def reverse_string(string) :
# split the string
string = string.split(' ')
n = len(string) - 1
rev_string = ''
while n >= 0 :
rev_string = rev_string + (string[n]) + ' '
n = n - 1
return rev_string
if __name__ == '__main__' :
string = input("Enter the string: ")
print(reverse_string(string).strip())
def reverse_string(string) :
# split the string
string = string.split(‘ ‘)
n = len(string) – 1
rev_string = ”
while n >= 0 :
rev_string = rev_string + (string[n]) + ‘ ‘
n = n – 1
return rev_string
if __name__ == ‘__main__’ :
string = input(“Enter the string: “)
print(reverse_string(string).strip())
https://uploads.disquscdn.com/images/cf02e6653b054797a297d4a7911b8e1539315433418f3ff821244b40c44b1e71.png
I did like this (split is a token function):
std::string reverseWords(std::string str){
std::vector list = split(str," ");
std::string r_string;
std::reverse(list.rbegin(), list.rend());
for(auto x:list){
r_string+=x+" ";
};
return r_string;
}
in python this is a one liner
print(' '.join([word[::-1] for word in input.split(' ')]))
Your first method is taking up the stack space though in recursion.
public static String reverseWord(String word) {
String [] splitting = word.split(” “);
String [] tempStringArray = new String[splitting.length];
for(int i=0;i<tempStringArray.length;i++)
{
tempStringArray[i] = splitting[splitting.length-i-1];
}
return String.join(" ",tempStringArray);
}
String reverseString(String [ ]s, int index){
if(index>=s.lenght) return "";
return s[0]+" "+reverseString(s,index+1);
}
Python3:
def reverseString(str):
temp = str.split(” “)
res = “”
for i in range(len(temp)):
res += temp[~i] + ” ”
return res[:-1]
Hello I wanna Ä‹hαt with youðŸ˜
https://google.com/#btnI=rutigunu&q=ichatster.com&ab=taubstxrcv
My id 457887
Inline without extra space
String reverseWords2(String input) {
int i = input.lastIndexOf(" ");
if(i == -1) {
//no space left, this is the first word
return input;
}
return input.substring(i+1) + " " + reverseWords2(input.substring(0, i));
}
WIth extra space but readable
String reverseWords(String input) {
if(input.isEmpty()) {
return input;
}
//split input into words
String[] wa = input.split(" ");
StringBuilder sb = new StringBuilder();
//create a new string buffer and fill it from backwards
for(int i = wa.length-1; i >=0; i--) {
sb.append(wa[i]);
sb.append(" ");
}
return sb.toString().trim();
}
Inline solution no extra space with recursion
String reverseWords2(String input) {
System.out.println(input);
int i = input.lastIndexOf(" ");
if(i == -1) {
//no space left, this is the first word
return input;
}
return input.substring(i+1) + " " + reverseWords2(input.substring(0, i));
}
Solution with extra space
String reverseWords(String input) {
//Read input
//split it into words
if(input.isEmpty()) {
return input;
}
String[] wa = input.split(" ");
StringBuilder sb = new StringBuilder();
//create a new string buffer and fill it from backwards
for(int i = wa.length-1; i >=0; i--) {
sb.append(wa[i]);
sb.append(" ");
}
return sb.toString().trim();
}
with python3:
def reverse(A):
n = len(A)
B = []
for i in range(n):
B.append(A.pop())
return B
def slice_reverse(A, j, k):
A[j:k] = reverse(A[j:k])
def reverseWords(S):
S = list(S)
n = len(S)
j=0
for i in range(n):
if S[i]==’ ‘:
slice_reverse(S, j, i)
j=i+1
slice_reverse(S, j, n+1)
return ”.join(reverse(S))
S = “the sky is blue”
reverseWords(S)
Java 8 solution:
public static void rev1(String[] a) {
String[] result = Stream.iterate(a.length - 1, i -> i - 1)
.limit(a.length)
.map(i -> a[i])
.toArray(String[] :: new);
Arrays.stream(result).forEach(System.out::println);
}
One line code in JavaScript:
function reverseString(str){
return str.split(' ').reverse().join(' ');
}
var str = "the sky is blue";
var output = reverseString(str);
document.write(output);
Minus one line:
public static void reverseWords(char[] s) {
int i=0;
for(int j=0; j<=s.length; j++){
if(j == s.length || s[j]==' '){
reverse(s, i, j-1);
i=j+1;
}
}
// reverse(s, i, s.length-1);
reverse(s, 0, s.length-1);
}
using System.Linq;
var output = string.Join(” “, s.Split(‘ ‘).Reverse());
#dotnetrocks 😉
var input = “ayman ali”;
input = ” ” + input;
var arr = input.ToCharArray();
var output = string.Empty;
var b = 0;
var e = arr.Length;
for (int p = arr.Length – 1; p >= 0; p–)
{
if (arr[p] == ‘ ‘ )// little off beginning of word
{
b = p + 1;
output += input.Substring(b, e – b) + ” “;
e = p ;
}
}
Console.WriteLine(output.TrimEnd(‘ ‘));
Console.ReadLine();
package java8fileread;
public class Rev {
public static void main(String[] args) {
String s = “hello”;
String rev = reverse(s.toCharArray(), ‘ ‘, s.length());
System.out.println(rev);
}
static String rev= “”;
private static String reverse(char[] charArray, char e, int length) {
if(length != 0)
{
if(e != ‘ ‘) rev += e;
reverse(charArray, charArray[–length], length) ;
}
return rev + charArray[0];
}
}
public static String reverse(String s) {
String tmp = new StringBuilder(s).reverse().toString();
char[] in = tmp.toCharArray();
int j = 0;
for (int i = 0; i < in.length; i++) {
if (in[i] == ' ') {
reverseChar(in, j, i – 1);
j = i + 1;
}
if (i == in.length-1)
{
reverseChar(in, j, i);
}
}
StringBuilder sb = new StringBuilder(in.length);
sb.append(in);
return sb.toString();
}
public static void reverseChar(char[] input, int i, int j) {
int b = j;
for (int a = i; a <= b; a++) {
char tmp = input[a];
input[a] = input[b];
input[b] = tmp;
b–;
}
//final StringBuilder sb = new StringBuilder(input.length);
//sb.append(input);
// System.out.print(sb.toString());
}
String word = “The sky is Blue”;
List wordList = Arrays.asList(word.split(” “));
Collections.reverse(wordList);
word = String.join(” “, (CharSequence[]) wordList.toArray());
System.out.println(word);
}
Two variant of solution using C#
class Program
{
static string reverseString1(string input)
{
char temp;
char[] s = input.ToCharArray();
for (int i = 0; i < s.Length / 2; temp = s[s.Length – 1 – i] , s[s.Length – 1 – i] = s[i] , s[i++] = temp ) ;
return new string(s);
}
static string reverseString2(string input)
{
char[] s = input.ToCharArray();
for (int i = 0; i < s.Length / 2; s[s.Length – 1 – i] ^= s[i], s[i] ^= s[s.Length – 1 – i], s[s.Length – 1 – i] ^= s[i++]) ;
return new string(s);
}
static void Main(string[] args)
{
string input = "abcd";
Console.WriteLine(reverseString1(input));
Console.WriteLine(reverseString2(input));
}
}
Trimming will get rid of the space between the words, that’s NOT what we want to do. I append space between the words so “sb.length() – 1” just deletes the last space.
Example: String s = “the sky is blue”;
*If you apply the TRIM you’ll get the following: “blueisskythe”.
*My application WITHOUT the “sb.length() – 1”: “blue is sky the ”
*My application WITH the “sb.length() – 1”: “blue is sky the”
setLength() is the most efficient way to get rid of the final space. Basically, it alters the count and overwrites the value we don’t want with a zero byte.
how about trimming the SB instead of setting the length?
funny, I had done something really similar:
public static String reverseWords(String str) {
StringBuilder sb = new StringBuilder();
int limit = str.length();
//from last to first
for (int i = str.length() – 1; i > 0; i–) {
if (str.charAt(i) == ‘ ‘) {
sb.append(str.substring(i + 1, limit)).append(‘ ‘);
limit = i;
}
}
sb.append(str.substring(0, limit));
return sb.toString();
}
public class Program
{
public static void Main(string[] args)
{
//Your code goes here
var input = "Hello";
Console.WriteLine(string.Format("Before reversing: - {0}",input));
var inPutArray = input.ToCharArray();
//var reversed = new StringBuilder();
//Reverse the string
for(int i= 0, j = inPutArray.Length - 1; i <= j;i++,j--){
var temp = inPutArray[i];
inPutArray[i] = inPutArray[j];
inPutArray[j] = temp;
}
Console.WriteLine(string.Format("After reversing: - {0}",new String(inPutArray)));
}
}
public static void ReverseString(String s) {
String[] split = s.split(" ");
StringBuilder sb = new StringBuilder();
for (int i = split.length - 1; i >= 0; i--) {
sb.append(split[i] + " ");
}
System.out.println(sb.setLength(sb.length() - 1).toString());
}
I liked this implementaion. Fast and efficinent.
I think from the moment you have array = string.split(” “); you are already using O(n) space, where n is the number of ‘ ‘ in the string.
String s="the sky is blue";
String[] s1=s.split("\s");
List l1=new ArrayList();
l1=Arrays.asList(s1);
Collections.reverse(l1);
System.out.println("this-:"+l1);
StringBuilder sb= new StringBuilder();
for(int y=0;y<l1.size();y++)
{
if(y==l1.size()-1)
{
sb.append(l1.get(y));
}
else
{
sb.append(l1.get(y)+" ");
}
}
String hy=sb.toString();
hy.trim();
System.out.print(hy);
i think using a stringbuilder or stringbuffer would be better as they expand and contract as opposed to Strings that are immutable. this way, you dont keep allocating new spaces for every new append you do.
String s = “the sky is blue”;
String[] splitted = s.split(” “);
System.out.println(Arrays.stream(splitted).reduce(“”,(a,b)->b+” “+a));
I have written this code and tried to keep it simple. I think I have considered space and time complexity as well at same time. What’s your input about it, please let me know.
public static String stringReverse(String string) {
if(string == null) {
return “”;
}
StringBuilder stringBuilder = new StringBuilder(“”);
for(int i = string.length() – 1; i >= 0; i–) {
if(Character.isWhitespace(string.charAt(i))) {
stringBuilder.append(string.substring(i + 1, string.length() – stringBuilder.length())).append(” “);;
}
}
stringBuilder.append(string.substring(0, string.length() – stringBuilder.length()));
return stringBuilder.toString();
}
public void reverseString() {
String original = “Please reverse me hello world”;
int staticPointer = original.length() – 1;
for (int movingPointer = original.length() – 1; movingPointer >= 0; movingPointer–) {
if (original.charAt(movingPointer) == ‘ ‘) {
int movingPointerTemp = movingPointer + 1;
while (movingPointerTemp <= staticPointer) {
System.out.print(original.charAt(movingPointerTemp));
movingPointerTemp = movingPointerTemp + 1;
}
staticPointer = movingPointer – 1;
System.out.print(" ");
}
}
for (int i = 0; i < staticPointer; i++) {
System.out.print(original.charAt(i));
}
}
private static String reverse(String string) {
// TODO Auto-generated method stub
String[] array = string.split(” “);
int start = 0;
int end = array.length – 1;
while(start < end){
String temp = array[start];
array[start] = array[end];
array[end] = temp;
start++;
end–;
}
String str1 = Arrays.toString(array);
return str1.substring(1,str1.length() – 1).replace(",", "");
}
Possible one liner in Scala
def reverseWords(s: String): String = s.split(' ').reverse.mkString(" ")
This works.
I have written this code, and I wonder if using the (“out” String) means allocating extra space?
public static String StringRev(String s)
{
String out="";
if(s==null)
return "";
for(int i=s.length()-1;i>0;i--)
{
if(Character.isWhitespace(s.charAt(i)))
{
s+=s.substring(i+1)+" ";
s= s.substring(0, i);
}
}
out+= s;
return out;
}
How about this…
public static String reverseWordsInString(String str){
String[] arr = str.split(” “);
String newArr = “”;
for(int index = arr.length – 1; index >= 0; –index)
newArr += ” ” + arr[index];
return newArr.substring(1);
}
…where I used the ‘substring’ method to produce an output without space. I’m very new to Java and relatively new to programming so I don’t know how Java’s ‘behind-the-scenes’ work, thus I don’t know if my code is more efficient.
cant use extra space
we cant use any extra space
He means the input string is not always “The sky is blue”. It may be longer than 4 words. In that case, the 4 line code solution by stefan fails.
public static void main(String[] args) {
// TODO Auto-generated method stub
String s=”my name is ab be fh”,temp;
String[] sDel=s.split(” “);
int j= sDel.length-1;
for(int i=0 ; i<(sDel.length/2) ; i++){
temp =sDel[i] ;
sDel[i] = sDel[j] ;
sDel[j] = temp;
j–;
}
for(int k=0;k<sDel.length;k++){
System.out.println(sDel[k]);
}
}
String s=”my name is ab be fh”,temp;
String[] sDel=s.split(” “);
int j= sDel.length-1;
for(int i=0 ; i<(sDel.length/2) ; i++){
temp =sDel[i] ;
sDel[i] = sDel[j] ;
sDel[j] = temp;
j–;
}
for(int k=0;k<sDel.length;k++){
System.out.println(sDel[k]);
}
the sky is not always blue 😀
In place? Without allocating extra space?
// 4 line of code not 14
public String reverseWordsInString(String str){
String[] arr = str.split(” “); // the sky is blue
String newArr = arr[3] + ” ” + arr[2] + ” ” + arr[0] +” “+ arr[1] ;
return newArr ;
}