一、题目
牛客题目链接:字符串变形_牛客题霸_牛客网
LeeCode 题目链接:
题目描述:
对于一个长度为 n 字符串,我们需要对它做一些变形。
首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。
比如"Hello World"变形后就变成了"wORLD hELLO"。
数据范围: 1≤n≤ , 字符串中包括大写英文字母、小写英文字母、空格。
进阶:空间复杂度 O(n) , 时间复杂度 O(n)
输入描述:
给定一个字符串s以及它的长度n(1 ≤ n ≤ 10^6)
返回值描述:
请返回变形后的字符串。题目保证给定的字符串均由大小写字母和空格构成。
示例1
输入:"This is a sample",16
返回值:"SAMPLE A IS tHIS"
示例2
输入:"nowcoder",8
返回值:"NOWCODER"
示例3
输入:"iOS",3
返回值:"Ios"
二、解题思路
方法一:双逆转(推荐使用)
思路:
首先把单词大小写反转(大写转小写,小写转大写),然后进行单词位置反转。
具体做法:
- step 1:遍历字符串,遇到小写字母,转换成大写,遇到大写字母,转换成小写,遇到空格正常不变。
- step 2:第一次反转整个字符串,这样基本的单词逆序就有了,但是每个单词的字符也是逆的。
- step 3:再次遍历字符串,以每个空间为界,将每个单词反转回正常。
图示:

复杂度分析:
- 时间复杂度:O(n),虽有多个循环,但是每个循环都只有一层O(n)
- 空间复杂度:O(n),res是存储变换的临时字符串,也可以直接用s直接变换,这样就为O(1)
方法二:分割字符串+栈(扩展思路)
知识点:栈
栈是一种仅支持在表尾进行插入和删除操作的线性表,这一端被称为栈顶,另一端被称为栈底。元素入栈指的是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;元素出栈指的是从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
思路:
题目要求将单词逆序,逆序我们就可以想到先进后出的栈,单词之间分开逆序我们需要整个字符串分割。
具体做法:
- step 1:遍历字符串,遇到小写字母,转换成大写,遇到大写字母,转换成小写,遇到空格正常不变。
- step 2:按照空格把字符串分割成一个个单词.
- step 3:遍历分割好的单词,将单词依次存入栈中。
- step 4:再从栈中弹出单词,拼接成字符串。
复杂度分析:
- 时间复杂度:O(n),所有循环最多遍历一次
- 空间复杂度:O(n),栈空间的大小最坏为O(n)
方法三:其他实现方案
- 双层循环,分别实现单词反转和字母反转;
- 按顺序循环字符串,遇到字母进行大小写反转,遇到空格进行位置反转。
三、代码实现:
方法一:双逆转(推荐使用)
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @param n int整型
* @return string字符串
*/
public String trans (String s, int n) {
// write code here
if (n == 0) {
return s;
}
StringBuffer res = new StringBuffer();
for (int i = 0; i < n; i++) {
//大小写转换
char c = s.charAt(i);
if (c >= 'a' && c <= 'z') {
res.append((char)(c + 'A'-'a'));
} else if (c >= 'A' && c <= 'Z') {
res.append((char)(c - 'A' + 'a'));
} else {
res.append(c); //空格直接复制
}
}
//反转整个字符串
res = res.reverse();
for (int i = 0; i < n; i++) {
int j = i;
//以空格为界,二次翻转
while (j < n && res.charAt(j) != ' ')
j++;
String temp = res.substring(i, j);
StringBuffer buffer = new StringBuffer(temp);
temp = buffer.reverse().toString();
res.replace(i, j, temp);
i = j;
}
return res.toString();
}
}
方法二:分割字符串+栈(扩展思路)
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @param n int整型
* @return string字符串
*/
public String trans (String s, int n) {
// write code here
if (n == 0) {
return s;
}
StringBuffer res = new StringBuffer();
for (int i = 0; i < n; i++) {
//大小写转换
char c = s.charAt(i);
if (c >= 'a' && c <= 'z') {
res.append((char)(c + 'A' - 'a'));
} else if (c >= 'A' && c <= 'Z') {
res.append((char)(c - 'A' + 'a'));
} else {
res.append((char)c); //空格直接复制
}
}
Stack<String> temp = new Stack<String>();
for (int i = 0; i < n; i++) {
int j = i;
//以空格为界,分割单词
while (j < n && res.charAt(j) != ' ')
j++;
//单词进栈
temp.push((String)(res.substring(i, j)));
i = j;
}
//排除结尾空格的特殊情况
if (s.charAt(n - 1) == ' ')
res = new StringBuffer(" ");
else
res = new StringBuffer();
//栈遵循先进后厨,单词顺序是反的
while (!temp.empty()) {
res.append(temp.peek());
temp.pop();
if (!temp.empty())
res.append(" ");
}
return res.toString();
}
}
方法三:其他实现方案
php:
<?php
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @param n int整型
* @return string字符串
*/
function trans( $s , $n )
{
// write code here
$result = [];
$arr = explode(' ',$s);
for($i=count($arr)-1; $i>=0;$i--){
$tmp = "";
for ($j=0; $j<strlen($arr[$i]); $j++){
$tmp .= transChar($arr[$i][$j]);
}
$result[] = $tmp;
}
return implode(' ', $result);
}
function transChar($char)
{
if ($char >= 'A' && $char <= 'Z') {
return strtolower($char);
}
if ($char >= 'a' && $char <= 'z') {
return strtoupper($char);
}
return $char;
}
java:
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @param n int整型
* @return string字符串
*/
public String trans (String s, int n) {
// write code here
StringBuffer res = new StringBuffer();
String tempStr = "";
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
if (c >= 'a' && c <= 'z') {
tempStr += Character.toUpperCase(c);
} else if (c >= 'A' && c <= 'Z') {
tempStr += Character.toLowerCase(c);
} else {
tempStr = c + tempStr;
res.insert(0, tempStr);
tempStr = "";
}
}
res.insert(0, tempStr);
return res.toString();
}
}
java:
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @param n int整型
* @return string字符串
*/
// 对每一个空格进行一次切分,防止出现"word hello"的情况
public String trans(String s, int n) {
// write code here
// 对每一个空格进行一次切分,防止出现"word hello"的情况
String[] arr = s.split(" ", -1);
StringBuilder res = new StringBuilder();
// 从右边开始处理并收集结果,注意空格的添加
for (int i = arr.length - 1; i >= 0; i--) {
res.append(reverse(arr[i]));
if (i == 0) {
break;
}
// 字符串间隔都要加上空格
res.append(" ");
}
return res.toString();
}
// 大小字母转换
private String reverse(String s) {
StringBuilder builder = new StringBuilder();
for (char c : s.toCharArray()) {
if (Character.isUpperCase(c)) {
builder.append(Character.toLowerCase(c));
} else {
builder.append(Character.toUpperCase(c));
}
}
return builder.toString();
}
}

2332

被折叠的 条评论
为什么被折叠?



