🚩传送门:牛客题目

题目

对于一个长度为 n 字符串,我们需要对它做一些变形。字符串中含有空格,就像"Hello World"一样,我们要做的是把这个字符串中由空格隔开的单词反序同时反转每个字符的大小写

比如"Hello World"变形后就变成了"wORLD hELLO"

数据范围: [NC]89. 字符串变形 - 图1 , 字符串中包括大写英文字母、小写英文字母、空格。
进阶:空间复杂度 [NC]89. 字符串变形 - 图2 , 时间复杂度 [NC]89. 字符串变形 - 图3
输入描述:给定一个字符串str以及它的长度n
返回值描述:请返回变形后的字符串。题目保证给定的字符串均由大小写字母和空格构成。

示例

输入:“This is a sample”,16 返回值:“SAMPLE A IS tHIS”

解题思路:栈

题目要求将单词逆序输出,很容易想到一个思路就是利用的先入后出特性。
[NC]89. 字符串变形 - 图4

复杂度分析

时间复杂度:[NC]89. 字符串变形 - 图5,其中 [NC]89. 字符串变形 - 图6 是字符串长度。

空间复杂度:[NC]89. 字符串变形 - 图7,需要栈将分割后的字符串重新存储一次。

我的代码

  1. public class Solution {
  2. public String trans(String s, int n) {
  3. LinkedList<StringBuffer>stack=new LinkedList<>(); // 栈
  4. StringBuffer tempbuffer =new StringBuffer(); // 存储临时转换的 String
  5. for(int i=0;i<=n;i++){ // 依次遍历字符串
  6. char c='+';
  7. if(i==n||(c=s.charAt(i))==' '){ // 遇到末尾结束或者空格时入栈
  8. stack.push(tempbuffer);
  9. tempbuffer = new StringBuffer(); // 重置清空当前StringBuffer
  10. }else{ // 大小写转换
  11. if(c >= 'a' && c <= 'z') tempbuffer.append((char)(c-'a'+'A'));
  12. else tempbuffer.append((char)(c-'A'+'a'));
  13. }
  14. }
  15. while(!stack.isEmpty()){ // 栈不空,出栈存储追加空格
  16. tempbuffer.append(stack.pop()).append(" ");
  17. }
  18. tempbuffer.deleteCharAt(tempbuffer.length()-1); // 删除最后一个末尾的空格
  19. return tempbuffer.toString(); // 转为String类型返回
  20. }
  21. }

解题思路:双指针

首先将原来的字符串整体反转,接着从前往后,以单个单词为整体逐个反转 。具体流程如下图所示:
image.png

复杂度分析

时间复杂度:[NC]89. 字符串变形 - 图9,其中 [NC]89. 字符串变形 - 图10 是字符串长度。

空间复杂度:[NC]89. 字符串变形 - 图11,需要栈将分割后的字符串重新存储一次。

我的代码

  1. public class Solution {
  2. public String trans(String s, int n) {
  3. // write code here
  4. if(s==null || n<=0){return s;}
  5. char[] sArr=s.toCharArray();
  6. //双指针 将字符串作为一个整体反转
  7. reverse(0,n-1,sArr);
  8. //各个单词作为一个整体 再反转一次
  9. int index=0;
  10. while(index<n){
  11. int end=index;
  12. while(end<n && sArr[end]!=' '){
  13. sArr[end]=upLower(sArr[end]);//大小写
  14. end++;
  15. }
  16. //找到空格了 单词的右边界为空格减一的位置
  17. reverse(index,end-1,sArr);
  18. index=end+1;//更新index 指向单词的首字母
  19. }
  20. return String.valueOf(sArr);
  21. }
  22. public void swap(int a,int b,char[]sArr){
  23. char tmp=sArr[a];
  24. sArr[a]=sArr[b];
  25. sArr[b]=tmp;
  26. }
  27. public void reverse(int start,int end,char[] sArr){
  28. int left=start,right=end;
  29. while(left<right){
  30. swap(left,right,sArr);
  31. left++;
  32. right--;
  33. }
  34. }
  35. public char upLower(char c){
  36. if(c>='a' && c<='z'){
  37. return (char)(c-32);//小写转大写
  38. }else if(c>='A' && c<='Z'){
  39. return (char)(c+32);//大写转小写
  40. }else{
  41. return c;//空格
  42. }
  43. }
  44. }