IT企业面试题(java描述)-字符串旋转(旋转字母或者单词)

这一章节我们来讨论一下IT企业面试题:字符串旋转(旋转字母或者单词)。

题目:

将字符串"abcdef"旋转成“defabc”

或者

将字符串"i am a student."旋转成"student. a am i"

而且在上面的题目里面还会加上不能够使用库函数的限制,我们下面将讨论解题的思路以及具体的代码。


1.思路

(1)暴力解法

就是一个字符一个字符的往后扔

(2)分部法

将不旋转部分和旋转部分分开来处理,先各自反转,再整体反转

(3)使用stack特性来处理


对于第一个题目我们可以使用第一第二种思路来处理,而第三种思路是在全部反转的时候更加出彩(如果是某几个旋转,第三种思路就会出现很多麻烦的处理,在这里不推荐使用)


2.具体代码

(1)下面的代码解题:将字符串"abcdef"旋转成“defabc”

package com.ray.datastructure.ch01.topic_1_1;

public class ReverseString_1 {

	private static String FirstCharToEnd(String source) {
		char[] charArray = source.toCharArray();
		char firstLetter = charArray[0];
		for (int i = 1; i < source.length(); i++) {
			charArray[i - 1] = charArray[i];
		}
		charArray[charArray.length - 1] = firstLetter;
		return new String(charArray);
	}

	public static String someCharsToEnd(String source, int countOfChar) {
		for (int i = 0; i < countOfChar; i++) {
			source = FirstCharToEnd(source);
		}
		return source;
	}

	public static void main(String[] args) {
		String source = "abcdef";
		System.out.println(someCharsToEnd(source, 3));
	}
}

测试输出:

defabc


上面是暴力解法,一个一个字符往后扔,因此造成时间复杂度是O(m*n)相对来说性能较差,当然,如果在笔试比较紧张的前提下,这个也算一个答案


(2)下面的代码解题:将字符串"abcdef"旋转成“defabc”

package com.ray.datastructure.ch01.topic_1_1;

public class ReverseString_2 {

	private static String reverse(String source, int start, int end) {
		char[] charArray = source.toCharArray();
		while (start < end) {
			char temp = charArray[start];
			charArray[start++] = charArray[end];
			charArray[end--] = temp;
		}
		return new String(charArray);
	}

	public static String reverse(String source, int pos) {
		if (pos > source.length()) {
			return "error:post is bigger than source's length";
		}
		source = reverse(source, 0, pos - 1);
		source = reverse(source, pos, source.length() - 1);
		source = reverse(source, 0, source.length() - 1);
		return source;
	}

	public static void main(String[] args) {
		String source = "abcdef";
		System.out.println(reverse(source, 3));
	}
}

测试输出:

defabc


上面的代码使用了分部法,首先把字符串看成两部分,一部分是需要移动的部分,就是上面的“abc”,另一部分是不需要移动的部分“def”,第二是把这两部分各自反转,变成“cba””fed“,现在返回的字符串是”cbafed“,第三是把”cbafed“这一个字符串整个反转,就变成了“defabc”了,这样的算法,时间复杂度变成了O(n)



(3)下面的代码解题:将字符串"i am a student."旋转成"student. a am i"

根据题目所给出的例子,我们这里应该是单词的调换,因此,就不再像上面的每一个字符的旋转

package com.ray.datastructure.ch01.topic_1_1;

public class ReverseString_3 {

	public static String reverse(String source, String regex, int start, int end) {
		String[] strArray = source.split(regex);
		while (start < end) {
			String temp = strArray[start];
			strArray[start++] = strArray[end];
			strArray[end--] = temp;
		}
		String rtnStr = "";
		for (int i = 0; i < strArray.length; i++) {
			rtnStr += strArray[i] + regex;
		}
		return rtnStr.trim();
	}

	public static void main(String[] args) {
		String source = "i am a student.";// student. a am i
		String regex = " ";
		System.out.println(reverse(source, regex, 0, source.split(regex).length - 1));
	}
}

测试输出:

student. a am i

从通用性来说,上面的这种方式比较好,因为它可以自定义调换的单词,暂时来说是最优实现



(4)下面的代码解题:将字符串"i am a student."旋转成"student. a am i"

对于这一题,我们如果允许使用库函数,可以引入栈的特性

package com.ray.datastructure.ch01.topic_1_1;

import java.util.Stack;

public class ReverseString_4 {

	public static String reverse(String source, String regex) {
		String[] strArray = source.split(regex);
		Stack<String> stack = new Stack<String>();
		for (String item : strArray) {
			stack.push(item);
		}
		String rtnStr = "";
		while (!stack.isEmpty()) {
			rtnStr += stack.pop() + regex;
		}
		return rtnStr.trim();
	}

	public static void main(String[] args) {
		String source = "i am a student.";// student. a am i
		String regex = " ";
		System.out.println(reverse(source, regex));
	}
}

测试输出:

student. a am i

上面的代码利用栈的先进后出的特性来实现题目

但是这里有局限性,它只是在全部旋转的前提下才好使,如果像上面的那种局部也可以调转的情况,就不推荐使用。


总结:这一章节介绍了字符串反转(旋转字母或者单词)的几种方法。

你可能感兴趣的:(java,面试题)