题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串为“I am a Student.",则输出为”Student. a am i".
这个题目是流传甚广,很多公司都多次拿来作为面试题,很多应聘者也多次在各种博客或者书籍上见到过通过两次翻转字符串的解法,于是很快可以跟面试官说出自己的思路:第一步反转句子中所有的字符。比如翻转“I am a Student"中所有的字符得到”.tneduts a ma i",此时不但翻转了句子中单词的顺序,连单词内的字符顺序也被翻转了。第二步再反转每个单词中字符的顺序,就得到了“student. a am I".这正是符合题目要求的输出。
Java代码实现如下:
/**
* 翻转单词的顺序VS左旋转单词的顺序
*/
package swordForOffer;
/**
* @author JInShuangQi
*
* 2015年8月10日
*/
public class E42ReverseWordsInSentence {
public String reverse(String str){
char[] array = str.toCharArray();
for(int i = 0;i<(array.length)/2;i++){
char temp = array[i];
array[i] = array[array.length-1-i];
array[array.length-i-1]=temp;
}
return String.valueOf(array);
}
public void reverseSentence(String sentence){
if(sentence == null)
return;
String sentenceReverse = reverse(sentence);
String[] splitStrings = sentenceReverse.split(" ");
String resultBuffer = "";
for(String s:splitStrings)
resultBuffer = resultBuffer+reverse(s)+" ";
System.out.println(resultBuffer);
}
}
有经验的面试官看到一个应聘者几乎不假思索的能想出一种比较巧妙的算法,就会觉得他之前可能见到过这个题目。这个时候很多面试官都会问一个问题,以考察他是不是真的理解了这个算法。面试官一个常见的考察办法就是问一个类似的但更加难一点的问题。
题目二:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转的功能。比如输入字符串”abcdefg"和数字2,该函数将返回左旋转2位得到的结果“cdefgab"
要找到字符串旋转时每个字符移动的规律,不是一件容易的事。那么我们是不是可以从解决第一个问题的思路中找到启发呢?在第一个问题中,如果输入的字符串之中只有两个单词,比如”hello World",那么翻转这个句子中的单词顺序就得到了“world hello",比较这两个字符串,我们是不是可以把”world hello"看成是把原始字符串“hello world"的前面若干个字符转移到后面?也就是说这两个问题非常相似,我们同样可以通过反转字符串的办法来解决第二个问题。
以”abcdeftg"为例,我们可以把它分为两个部分,由于想把它的前两个字符一道后面,我们就把前面两个字符分到第一部分,把后面的所有字符都分到第二个部分。我们先反转这两部分,于是就得到了“bagfedc",接下来我们再翻转整个字符串,得到了”cdefgab"刚好就是把原始字符串左旋转2位的结果。
通过分析我们可以写出下面代码:
/**
* 左旋转字符串
*/
package swordForOffer;
/**
* @author JInShuangQi
*
* 2015年8月10日
*/
public class E42LeftRotateString {
public String reverse(String str){
char[] arr = str.toCharArray();
for(int i = 0;i<(arr.length+1)/2;i++){
char temp = arr[i];
arr[i] = arr[arr.length-i-1];
arr[arr.length-i-1]= temp;
}
return String.valueOf(arr);
}
public void leftRotateString(String sentence,int index){
if(sentence == null || index >sentence.length() || index <0)
return;
String[] splitStrings = {sentence.substring(0, index),sentence.substring(index, sentence.length())};
String resultBuffer = "";
for(int i =0;i<splitStrings.length;i++){
splitStrings[i] =reverse(splitStrings[i]);
resultBuffer+=splitStrings[i];
}
System.out.println(reverse(resultBuffer));
}
public static void main(String[] args){
String str= "abcdefg";
E42LeftRotateString test = new E42LeftRotateString();
test.leftRotateString(str, 2);
}
}
相清楚思路写代码是一件容易的事,但我们不能掉以轻心。面试官在检查与字符串相关的代码时经常会发现两种问题,一是输入控制帧NULL时程序会崩溃,二是内存访问越界的问题。所以我们不能排除这两种情况的存在。