前言
之前小六六一直觉得自己的算法比较菜,算是一个短板吧,以前刷题也还真是三天打鱼,两天晒网,刷几天,然后就慢慢的不坚持了,所以这次,借助平台的活动,打算慢慢的开始开刷,并且自己还会给刷的题总结下,谈谈自己的一些思考,和自己的思路等等,希望对小伙伴能有所帮助吧,也可以借此机会把自己短板补一补,希望自己能坚持下去呀
链表的合集
前面就是全部数组的题了,从今天开始我们来刷刷字符串相关的题吧
题目
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题
示例 1:
输入:s = ["h","e","l","l","o"] 输出:["o","l","l","e","h"] 示例 2:
输入:s = ["H","a","n","n","a","h"] 输出:["h","a","n","n","a","H"]
解析
其实这个题,大家在开发的过程中肯定会碰到过,让你反转字符串,在Java StringBuffer类中有一个Reverse方法,用来对字符串反转,如StringBuffer x=new StringBuffer('helloworld'), 使用Reverse方法后获得新字符串'dlrowolleh',那么我们刚好借着这题,我们来聊聊Java这个方法的原理,那么对我们写这题肯定是有帮助的
public AbstractStringBuilder reverse() { boolean hasSurrogates = false; int n = count - 1; for (int j = (n-1) >> 1; j >= 0; j--) { int k = n - j; char cj = value[j]; char ck = value[k]; value[j] = ck; value[k] = cj; if (Character.isSurrogate(cj) || Character.isSurrogate(ck)) { hasSurrogates = true; } } if (hasSurrogates) { reverseAllValidSurrogatePairs(); } return this; } /** Outlined helper method for reverse() */ private void reverseAllValidSurrogatePairs() { for (int i = 0; i < count - 1; i++) { char c2 = value[i]; if (Character.isLowSurrogate(c2)) { char c1 = value[i + 1]; if (Character.isHighSurrogate(c1)) { value[i++] = c1; value[i] = c2; } } } }
可以看出,StringBuffer逆序也是基于char数组,循环次数(时间复杂度)
题解 双指针法
对于长度为 N 的待被反转的字符数组,我们可以观察反转前后下标的变化,假设反转前字符数组为 s[0] s[1] s[2] ... s[N - 1],那么反转后字符数组为 s[N - 1] s[N - 2] ... s[0]。比较反转前后下标变化很容易得出 s[i] 的字符与 s[N - 1 - i] 的字符发生了交换的规律,因此我们可以得出如下双指针的解法:
将 left 指向字符数组首元素,right 指向字符数组尾元素。 当 left < right: 交换 s[left] 和 s[right]; left 指针右移一位,即 left = left + 1; right 指针左移一位,即 right = right - 1。 当 left >= right,反转结束,返回字符数组即可。
class Solution { public void reverseString(char[] s) { int n = s.length; for (int left = 0, right = n - 1; left < right; ++left, --right) { char tmp = s[left]; s[left] = s[right]; s[right] = tmp; } } }
其实核心就是我们 swp,这个也是我们经常用到的,要记住哈
int tmp = s[i]; s[i] = s[j]; s[j] = tmp;
再来个做法
要是我用Java来写,是不是可以把String 变成 char[]数组,然后从后面可以遍历,然后累加,代码如下,这样的话就开辟了新的内存了
private static String reverse2(String str) { if (str == null) { return null; } String result = ""; char[] chars = str.toCharArray(); for (int i = chars.length - 1; i >= 0; i--) { result = result + chars[i]; } return result; }
结束
好了,从今天开始我们开始刷我们的字符串了,大家加油,我是小六六,三天打鱼,两天晒网!