344.反转字符串
题目
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
来源:力扣(LeetCode)
链接:反转字符串
解法
思路
- 时间复杂度:O(n)
- 空间复杂度:O(1)
// 第一种
class Solution {
public void reverseString(char[] s) {
//前后插入指针
int i = 0;
int j = s.length - 1;
while(i < j){
char temp = s[i];
s[i] = s[j];
s[j] = temp;
i++;
j--;
}
}
}
// 第二种
class Solution {
public void reverseString(char[] s) {
int i = 0;
int j = s.length - 1;
while(i < j){
//构造 a ^ b 的结果,并放在 a 中
s[i] ^= s[j];
//将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ b
s[j] ^= s[i];
//a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换
s[i] ^= s[j];
i++;
j--;
}
}
}
剑指 Offer05.替换空格
题目
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
来源:力扣(LeetCode)
链接:替换空格
replace(替换)
class Solution {
public String replaceSpace(String s) {
return s.replace(" ","%20");
}
}
剑指 Offer58 - l.翻转单词顺序
题目
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。
来源:力扣(LeetCode)
链接:翻转单词顺序
方法一
- 时间复杂度:O(n)
- 空间复杂度:O(n)
class Solution {
public String reverseWords(String s) {
s = s.trim();
List<String> ans = Arrays.asList(s.split("\\s+"));
Collections.reverse(ans);
return String.join(" ", ans);
}
}
方法二,双端队列
- 时间复杂度:O(n)
- 空间复杂度:O(n)
class Solution {
public String reverseWords(String s) {
int i = 0;
int j = s.length() - 1;
//消除开头的空白
while(i <= j && s.charAt(i) == ' '){
i++;
}
//消除末尾的空白
while(i <= j && s.charAt(j) == ' '){
j--;
}
Deque<String> deque = new ArrayDeque<>();
StringBuilder word = new StringBuilder();
while(i <= j){
char ch = s.charAt(i);
if((word.length() != 0) && (ch == ' ')){
deque.offerFirst(word.toString());
word.setLength(0);
}else if(ch != ' '){
word.append(ch);
}
i++;
}
deque.offerFirst(word.toString());
return String.join(" ", deque);
}
}
剑指 Offer58 - ll.左旋转字符串
题目
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
来源:力扣(LeetCode)
链接:左旋转字符串
substring(切片函数)
- 时间复杂度:O(N),N是字符串长度
- 空间复杂度:O(N),N是切片后的字符串长度
class Solution {
public String reverseLeftWords(String s, int n) {
return s.substring(n) + s.substring(0, n);
}
}
遍历拼接字符串
- 时间复杂度:O(N),N是字符串长度
- 空间复杂度:O(N),N是切片后的字符串长度
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder res = new StringBuilder();
for(int i = n; i < s.length(); i++){
res.append(s.charAt(i));
}
for(int i = 0; i < n; i++){
res.append(s.charAt(i));
}
return res.toString();
}
}
字符串遍历拼接
- 时间复杂度:O(N),N是字符串长度
- 空间复杂度:O(N),N是切片后的字符串长度
class Solution {
public String reverseLeftWords(String s, int n) {
String res = "";
for(int i = n; i < s.length(); i++){
res += s.charAt(i);
}
for(int i = 0; i < n; i++){
res += s.charAt(i);
}
return res;
}
}
反转-反转-再反转
- 时间复杂度: O(n)
- 空间复杂度:O(1)
思路
先整个字符串反转,再反转前面的,最后反转后面 n 个
class Solution {
public String reverseLeftWords(String s, int n) {
char[] chars = s.toCharArray();
reverse(chars, 0, chars.length - 1);
reverse(chars, 0, chars.length - 1 - n);
reverse(chars, chars.length - n, chars.length - 1);
return new String(chars);
}
public void reverse(char[] chars, int left, int right){
while(left < right){
chars[left] ^= chars[right];
chars[right] ^= chars[left];
chars[left] ^= chars[right];
left++;
right--;
}
}
}