题目链接:反转字符串
题目描述:
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 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 l = 0;
int r = s.length - 1;
while (l < r) {
s[l] ^= s[r]; //构造 a ^ b 的结果,并放在 a 中
s[r] ^= s[l]; //将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ b
s[l] ^= s[r]; //a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换
l++;
r--;
}
}
}
题目链接:反转字符串 II
题目描述:
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
解题思路:从题目中可以看出,我们可以将整个字符串每2k个分为一个子字符串,因此我们可以将我们的循环跳步设为2k个,然后在每次循环中处理这个子字符串,从题目要求中可以看出就是将这个子字符串中的前k个反转,剩下的保持原样,那么就可以采用第一题的算法进行反转。
代码实现:
class Solution {
public String reverseStr(String s, int k) {
int count=0;
char[] sch=s.toCharArray();
int i=0;
while(i<sch.length){
int start=i;
int end=Math.min(sch.length-1,i+k-1);
if(end<sch.length){
while(start<end){
sch[start]^=sch[end];
sch[end]^=sch[start];
sch[start]^=sch[end];
start++;
end--;
}
}
i+=2*k;
}
return new String(sch);
}
}
题目链接:替换数字
题目描述:
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 “a1b2c3”,函数应该将其转换为 “anumberbnumbercnumber”。
解题思路:
因为java的string内容不可改,因此需要辅助空间,构造一个新的空间来储存新的内容,所以我们首先要确定新的数组的长度,通过依次遍历来确定新的数组空间,然后我们可以采用双指针法,从后往前遍历,一个指针指向就指针结尾一个指针指向新指针末尾,来判断两种情况一种为字母不变,一种为数字修改为number。
代码实现:
import java.util.Scanner;
public class Main{
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
char[] ch=s.toCharArray();
int count=ch.length;
for(int i=0; i<ch.length;i++){
if(ch[i] >='0'&&ch[i]<='9'){
count+=5;
}
}
char[] res = new char[count];
for(int i=ch.length-1,j=count-1;i>=0;i--,j--){
if(ch[i] >='0'&&ch[i]<='9'){
res[j--]='r';
res[j--]='e';
res[j--]='b';
res[j--]='m';
res[j--]='u';
res[j]='n';
}else{
res[j]=ch[i];
}
}
System.out.println(new String(res));
}
}
题目链接:反转字符串中的单词
题目描述:
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
解题思路:本题借用官方题解图
采用三步去除多余空格,之后反转整个字符串,然后逐个反转单词即可得到答案。
代码实现:
class Solution {
public String reverseWords(String s) {
char[] ch = s.toCharArray();
ch = removeExtraSpaces(ch);
reverse(ch, 0, ch.length - 1);
reverseEachWord(ch);
return new String(ch);
}
public char[] removeExtraSpaces(char[] ch){
int slow=0;
for(int fast=0;fast<ch.length;fast++){
if(ch[fast]!=' '){
while(fast<ch.length&&ch[fast]!=' '){
ch[slow++]=ch[fast++];
}
while(fast<ch.length&&ch[fast]==' '){
fast++;
}
if(fast<ch.length){
ch[slow++]=' ';
}
fast--;
}
}
char[] newCh = new char[slow];
System.arraycopy(ch, 0, newCh, 0, slow);
return newCh;
}
public void reverse(char[] ch, int left, int right) {
if (right >= ch.length) {
return;
}
while (left < right) {
ch[left] ^= ch[right];
ch[right] ^= ch[left];
ch[left] ^= ch[right];
left++;
right--;
}
}
public void reverseEachWord(char[] ch) {
int start = 0;
for (int end = 0; end <= ch.length; end++) {
if (end == ch.length || ch[end] == ' ') {
reverse(ch, start, end - 1);
start = end + 1;
}
}
}
}
题目链接:右旋字符串
题目描述:
字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 “abcdefg” 和整数 2,函数应该将其转换为 “fgabcde”。
解题思路:通过上一道题我们可以很轻松想到先把整个字符串反转,然后分别反转前n个和剩余字符串来得到答案。
代码实现:
import java.util.Scanner;
public class Main{
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
in.nextLine();
String s= in.nextLine();
char[] ch = s.toCharArray();
reverse(ch,0,ch.length-1);
reverse(ch,0,n-1);
reverse(ch,n,ch.length-1);
System.out.println(new String(ch));
}
public static void reverse(char[] ch,int left, int right){
if (right >= ch.length) {
return;
}
while (left < right) {
ch[left] ^= ch[right];
ch[right] ^= ch[left];
ch[left] ^= ch[right];
left++;
right--;
}
}
}