LeetCode 344.反转字符串
简单题,注意循环的结束条件,踩坑:当数组的长度为偶数时,需要特殊处理一下s[s.length/2 -1]和s[s.length/2]。代码如下:
class Solution {
public void reverseString(char[] s) {
int k = 0;
for(int i=s.length-1; i>s.length/2; i--){
char temp = s[i];
s[i] = s[k];
s[k] = temp;
k++;
}
if(s.length % 2 == 0){
char temp = s[s.length/2];
s[s.length/2] = s[s.length/2 - 1];
s[s.length/2 - 1] = temp;
}
}
}
LeetCode 541. 反转字符串II
想法:本题与上题解法相似,每隔2k个反转前k个,最后如果数组长度整除k为偶数且有剩余字符,则全部反转,代码如下:
class Solution {
public void reverse(char[] s, int start, int kn){
int k=start;
for(int i=start + kn-1; i> start + kn / 2; i--){
char temp = s[i];
s[i] = s[k];
s[k] = temp;
k++;
}
if(kn % 2 == 0){
char temp = s[start + kn / 2];
s[start + kn / 2] = s[start + kn / 2 - 1];
s[start + kn / 2 - 1] = temp;
}
}
public String reverseStr(String s, int k) {
int count = s.length() / k;
char[] ss = s.toCharArray();
for(int i=0; i<count; i++){
if(i %2 == 0){
// 反转字符
reverse(ss, i*k, k);
}
}
if(count % 2 == 0 && s.length() > count * k){
// 若模2k==0,且有剩余字符,则剩余字符全部反转
reverse(ss, count*k, s.length()-count*k);
}
return new String(ss);
}
}
剑指Offer 05.替换空格
刚开始用split方法过滤掉空格,但是发现处理不了" "这种全是空格或者字符之间有多个空格的情况,最后只好转换为字符数组,逐个遍历,代码如下:
class Solution {
public String replaceSpace(String s) {
char[] ss = s.toCharArray();
String result = new String();
for(int i=0; i<ss.length; i++){
if(ss[i] == ' '){
result = result + "%20";
}else{
result = result + ss[i];
}
}
return result;
}
}
151.翻转字符串里的单词
首先去掉字符串首尾的空格,然后用split函数根据空格进行划分,类似于反转字符串一样的方法来反转单词顺序。踩坑:最后拼接字符串时,如果为空要continue,不然字符串内会有多余空格。代码如下:
class Solution {
public String reverseWords(String s) {
String[] ss = s.trim().split(" ");
String result = new String();
int k = 0;
for(int i=ss.length-1; i> ss.length/2; i--){
String temp = ss[i];
ss[i] = ss[k];
ss[k] = temp;
k++;
}
if(ss.length % 2 == 0){
String temp = ss[ss.length/2];
ss[ss.length/2] = ss[ss.length/2 -1];
ss[ss.length/2 - 1] = temp;
}
for(int i=0; i<ss.length; i++){
if(ss[i] == "") continue;
String item = ss[i].trim();
if(i == 0){
result = item;
}else {
result = result + " " + item;
}
}
return result;
}
}
这个题的难度是中等,但如果按我的思路来写就太简单了,抱着这一丝丝的犹豫点开了卡尔的文章,哈哈哈哈果不其然是我想简单了。于是乎按照文章的想法,重新写了一遍题。代码如下:
class Solution {
public void reverse(char[] s, int start, int end){
// 反转从start到end位置的字符(左闭右开)
for(int i=end-1, j = start; i>j; i--, j++){
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
public String reverseWords(String s) {
char[] ss = s.toCharArray();
// 1.去除多余的空格
int slow = 0;
int k = 0;
for(int i=0; i<ss.length; i++){
if(ss[i] != ' '){
if(slow != 0) ss[slow++] = ' ';
while(i < ss.length && ss[i] != ' '){
ss[slow++] = ss[i++];
}
}
}
// 2.反转整个字符串
reverse(ss, 0, slow);
// 3.反转单词
int start = 0;
int end = 0;
while(end < slow){
if(ss[end] != ' '){
end++;
}else{
reverse(ss, start, end);
end++;
start = end;
}
}
reverse(ss, start, end); // 翻转最后一个单词
return new String(ss, 0, slow);
}
}
剑指Offer58-II.左旋转字符串
简单水题解法:因为对java的操作并不熟悉,本着以在笔试时应最快方法解决问题,所以水题解法也会做一遍,主要是为了熟悉操作。代码如下:
class Solution {
public String reverseLeftWords(String s, int n) {
return s.substring(n, s.length()) + s.substring(0, n);
}
}
翻转解法:1.先反转前n个字符;2.接着反转n到末尾字符;3.最后反转整个字符串,便可以得到最后的结果。代码如下:
class Solution {
public void reverse(char[] s, int start, int end){
for(int i=start, j=end-1; i<j; i++, j--){
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
public String reverseLeftWords(String s, int n) {
char[] ss = s.toCharArray();
reverse(ss, 0, n);
reverse(ss, n, ss.length);
reverse(ss, 0, ss.length);
return new String(ss, 0, ss.length);
}
}
总结
后两道简单题用O(1)空间复杂度来写,对字符串的反转操作更熟悉了。