双指针 字符串
题目描述 给你一个字符数组 s ,反转其中 单词 的顺序。
单词 的定义为:单词是一个由非空格字符组成的序列。s 中的单词将会由单个空格分隔。
必须设计并实现 原地 解法来解决此问题,即不分配额外的空间。
示例 1:
输入: s = ["t","h","e"," ","s","k","y"," ","i","s"," ","b","l","u","e"]
输出: ["b","l","u","e"," ","i","s"," ","s","k","y"," ","t","h","e"]
示例 2:
输入: s = ["a"]
输出: ["a"]
提示:
1 <= s.length <= 105 s[i] 可以是一个英文字母(大写或小写)、数字、或是空格 ' ' 。 s 中至少存在一个单词 s 不含前导或尾随空格 题目数据保证:s 中的每个单词都由单个空格分隔 解法 方法一:双指针 思考
字符数组上原地反转单词顺序,词间恰有一个空格,无首尾空格。\(n\le 10^5\) ,额外 \(O(1)\) 空间。先反转每个单词,再反转整个数组,单词顺序颠倒而词内字符恢复正向。双指针框住每个词的左右端。
我们可以遍历字符数组 \(s\) ,利用双指针 \(i\) 和 \(j\) 找到每个单词的起始位置和结束位置,然后反转每个单词,最后再反转整个字符数组。
时间复杂度 \(O(n)\) ,其中 \(n\) 为字符数组 \(s\) 的长度。空间复杂度 \(O(1)\) 。
Python3 Java C++ Go TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 class Solution :
def reverseWords ( self , s : List [ str ]) -> None :
def reverse ( i : int , j : int ):
while i < j :
s [ i ], s [ j ] = s [ j ], s [ i ]
i , j = i + 1 , j - 1
i , n = 0 , len ( s )
for j , c in enumerate ( s ):
if c == " " :
reverse ( i , j - 1 )
i = j + 1
elif j == n - 1 :
reverse ( i , j )
reverse ( 0 , n - 1 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 class Solution {
public void reverseWords ( char [] s ) {
int n = s . length ;
for ( int i = 0 , j = 0 ; j < n ; ++ j ) {
if ( s [ j ] == ' ' ) {
reverse ( s , i , j - 1 );
i = j + 1 ;
} else if ( j == n - 1 ) {
reverse ( s , i , j );
}
}
reverse ( s , 0 , n - 1 );
}
private void reverse ( char [] s , int i , int j ) {
for (; i < j ; ++ i , -- j ) {
char t = s [ i ] ;
s [ i ] = s [ j ] ;
s [ j ] = t ;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 class Solution {
public :
void reverseWords ( vector < char >& s ) {
auto reverse = [ & ]( int i , int j ) {
for (; i < j ; ++ i , -- j ) {
swap ( s [ i ], s [ j ]);
}
};
int n = s . size ();
for ( int i = 0 , j = 0 ; j < n ; ++ j ) {
if ( s [ j ] == ' ' ) {
reverse ( i , j - 1 );
i = j + 1 ;
} else if ( j == n - 1 ) {
reverse ( i , j );
}
}
reverse ( 0 , n - 1 );
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 func reverseWords ( s [] byte ) {
reverse := func ( i , j int ) {
for ; i < j ; i , j = i + 1 , j - 1 {
s [ i ], s [ j ] = s [ j ], s [ i ]
}
}
i , n := 0 , len ( s )
for j , c := range s {
if c == ' ' {
reverse ( i , j - 1 )
i = j + 1
} else if j == n - 1 {
reverse ( i , j )
}
}
reverse ( 0 , n - 1 )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 /**
Do not return anything, modify s in-place instead.
*/
function reverseWords ( s : string []) : void {
const n = s . length ;
const reverse = ( i : number , j : number ) : void => {
for (; i < j ; ++ i , -- j ) {
[ s [ i ], s [ j ]] = [ s [ j ], s [ i ]];
}
};
for ( let i = 0 , j = 0 ; j <= n ; ++ j ) {
if ( s [ j ] === ' ' ) {
reverse ( i , j - 1 );
i = j + 1 ;
} else if ( j === n - 1 ) {
reverse ( i , j );
}
}
reverse ( 0 , n - 1 );
}
GitHub