文章目录
- 一、反转字符串(力扣344)
- 二、反转字符串中的元音字母(力扣345)
- 三、反转字符串 II(力扣541)
- 四、反转字符串中的单词 III(力扣557)
- 五、替换空格(剑指 Offer 05)
- 六、翻转字符串里的单词(力扣151)
- 七、左旋转字符串(剑指Offer58-II)
一、反转字符串(力扣344)
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
较为简单
class Solution {
public void reverseString(char[] s) {
int l = 0;
int r = s.length-1;
while(l<r){
char temp = s[l];
s[l]=s[r];
s[r]=temp;
l++;
r--;
}
}
}
二、反转字符串中的元音字母(力扣345)
给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 ‘a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现。
参考一次快排思路:
class Solution {
public String reverseVowels(String s) {
char[] ss = s.toCharArray();
String title = "aeiouAEIOU";
int l=0;
int r=ss.length-1;
while(l<r){
while(l<r && title.indexOf(ss[l])< 0){
l++;
}
while(l<r && title.indexOf(ss[r])< 0){
r--;
}
char temp = ss[l];
ss[l] = ss[r];
ss[r] = temp;
l++;
r--;
}
return String.valueOf(ss);
}
}
三、反转字符串 II(力扣541)
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
- 如果剩余字符少于 k 个,则将剩余字符全部反转。
- 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
class Solution {
public String reverseStr(String s, int k) {
char[] ss = s.toCharArray();
for(int i=0;i<ss.length;i+=2*k){
//反转i-i+k的字符
int left = i;
int right = i+k-1;
if(right<=ss.length-1){ //不要超过数组的长度
while(left<right){
char temp = ss[left];
ss[left] = ss[right];
ss[right] = temp;
left++;
right--;
}
continue;
}
left = i;
right = ss.length-1;
while(left<right){
char temp = ss[left];
ss[left] = ss[right];
ss[right] = temp;
left++;
right--;
}
}
return String.valueOf(ss);
}
}
四、反转字符串中的单词 III(力扣557)
给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序
class Solution {
public String reverseWords(String s) {
char[] ss = s.toCharArray();
int i = 0;
int j = 0;
for(;j<ss.length; j++){//跳到下一个单词的起始位置
if(ss[j]==' '){
//反转单词
int left = i;
int right=j-1;
while(left<right){
char temp = ss[left];
ss[left] = ss[right];
ss[right] = temp;
left++;
right--;
}
i=j+1;
j=i;
}
}
int left = i;
int right = ss.length-1;
while(left<right){
char temp = ss[left];
ss[left] = ss[right];
ss[right] = temp;
left++;
right--;
}
return String.valueOf(ss);
}
}
五、替换空格(剑指 Offer 05)
请实现一个函数,把字符串 s 中的每个空格替换成"%20"
双指针法:
按照正常思路 从前往后遍历,碰到空格时,所有元素需要向后挪动两个单位,时间复杂度较大。
很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
class Solution {
public String replaceSpace(String s) {
StringBuilder str = new StringBuilder();
for(int i=0;i<s.length();i++){
if(s.charAt(i)==' '){
str.append(" ");//扩充字符串的大小
}
}
//如果没有空格直接返回
if(str.length()==0){
return s;
}
//定义两个指针
int left = s.length()-1; //指向最后一个位置
s +=str.toString();
int right = s.length()-1;//指向扩展字符串的最后一个位置
char[] chars= s.toCharArray();
while(left>=0){
if(chars[left]==' '){
chars[right--]='0';
chars[right--]='2';
chars[right]='%';
}else{
chars[right]=chars[left];
}
left--;
right--;
}
return new String(chars);
}
}
六、翻转字符串里的单词(力扣151)
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
思路:
- 移除多余空格----数组之移除元素(力扣27)当移除完后记得更新数组的长度
- 将整个字符串反转------反转字符串(力扣344)
- 将每个单词反转-----反转字符串中的单词 III(力扣557)
举个例子,源字符串为:"the sky is blue "
- 移除多余空格 : “the sky is blue”
- 字符串反转:“eulb si yks eht”
- 单词反转:“blue is sky the”
难点在于把多余的空格移除
class Solution {
public String reverseWords(String s) {
char[] chars = s.toCharArray();
//双指针法移除多余的空格
int slowIndex=0;
int fastIndex=0;
for(fastIndex=0;fastIndex<chars.length;fastIndex++){
if(chars[fastIndex]!=' '){
if(slowIndex!=0){
chars[slowIndex++]=' ';
}
while(fastIndex<chars.length && chars[fastIndex]!=' '){
chars[slowIndex++] = chars[fastIndex++];
}
}
}
char[] newChars = new char[slowIndex];
System.arraycopy(chars, 0, newChars, 0, slowIndex);
//整个字符串反转
int left=0;
int right=newChars.length-1;
while(left<right){
char temp = newChars[left];
newChars[left]=newChars[right];
newChars[right]=temp;
left++;
right--;
}
//将单词反转
String res = reverseWords(newChars);
return res;
}
public String reverseWords(char[] ss) {
int i = 0;
int j = 0;
for(;j<ss.length; j++){//跳到下一个单词的起始位置
if(ss[j]==' '){
//反转单词
int left = i;
int right=j-1;
while(left<right){
char temp = ss[left];
ss[left] = ss[right];
ss[right] = temp;
left++;
right--;
}
i=j+1;
j=i;
}
}
int left = i;
int right = ss.length-1;
while(left<right){
char temp = ss[left];
ss[left] = ss[right];
ss[right] = temp;
left++;
right--;
}
return String.valueOf(ss);
}
}
七、左旋转字符串(剑指Offer58-II)
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
思路:
参考上一题:整体翻转+局部翻转
class Solution {
public String reverseLeftWords(String s, int n) {
char[] chars = s.toCharArray();
//整体翻转
int left =0;
int right=chars.length-1;
while(left<right){
char temp = chars[left];
chars[left] = chars[right];
chars[right]=temp;
left++;
right--;
}
//局部翻转
//翻转第一部分
int left1=0;
int right1 = chars.length-n-1;
while(left1<right1){
char temp = chars[left1];
chars[left1] = chars[right1];
chars[right1]=temp;
left1++;
right1--;
}
//翻转第二部分
int left2=chars.length-n;
int right2 = chars.length-1;
while(left2<right2){
char temp = chars[left2];
chars[left2] = chars[right2];
chars[right2]=temp;
left2++;
right2--;
}
return String.valueOf(chars);
}
}