题目一:把带有空格的一句话例如:I am a boy 变成 boy a am I
单词顺序全部反转,但是单词内部的字母顺序以及空格相对位置不能变。
思路:一次就转换成功看起来有些困难,于是这里分两步进行。
I am a boy --> yob a ma I -->boy a am I
首先将数组全部反转,但发现这时候单词中的字母顺序也改变了,因此还需要进行一次单词内部的反转。从这里可以看出,我们需要进行两次反转操作。在写代码的时候就要注意了。
根据传的参数确定反转的位置 函数:这里参数写进去要反转的起始位置,方便后续操作。在确定循环中交换的位置的时候可以先模拟几个数字,找规律。
public static void reverseArray(char[] words,int start,int end) { int length = end - start; for (int i = 0; i < length/2; i++) { char temp = words[end-1-i]; words[end-1-i] = words[start+i]; words[start+i] = temp; } }
反转函数:注意,这里首先要将整个句子反转,得到中间的状态。思考如何反转单词内部呢?这里注意到每遇到一个空格就相当于马上有下一个单词了,所以可以根据空格确定要反转的小单词的位置。注意最后一个单词。
public static void swapString(char[] words) { int length = words.length; int i = 0, j = 0; reverseArray(words, 0, length); for (i = 0; i <= length-1; i ++) { if (words[i]==' ') { reverseArray(words, j, i); j = i + 1; } } reverseArray(words, j, i); }
题目二:把数组的后面k个元素移到前面。例如 wqmdnzxln1234 把后面6个移到前面,变为ln1234wqmdnzx。
思路:虽然此题有很多种解法,例如可以新建一个数组,然后找到原数组后面k个,先放入新数组,再将剩下的放入新数组。但这样需要重新开辟一个O(n)的空间,时间复杂度也很高。我们需要另外想一个更好的方案。
根据上面一道题,我们可以进行两次操作。 wqmdnzxln1234 -->4321nlxzndmqw-->ln1234wqmdnzx
相当于先反转整个数组,然后再分别反转前面k个和剩下的部分。
public static void swapKArr(char[] words,int k) { int length = words.length; int i = 0,j = 0; reverseArray(words,0,length); reverseArray(words,0,k); reverseArray(words,k,length); }