文章目录
leetcode344,反转字符数组
问题描述
解决方案:设置一个暂存变量就好了
这个题目的意义:「如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数。」
「如果库函数仅仅是 解题过程中的一小部分,并且你已经很清楚这个库函数的内部实现原理的话,可以考虑使用库函数。」
0^ 0=0; 0^ 1=1; 1^ 0=1; 1^ 1=0
class Solution {
public void reverseString(char[] s) {
for (int left=0,right=s.length-1; left<right; left++,right--){
char mychar = s[left];
s[left] = s[right];
s[right] = mychar;
}
}
}
可以向下面一样,改成while循环,如下:
class Solution {
public void reverseString(char[] s) {
int left =0;int right = s.length -1;
while ( left<right ){
char mychar = s[left];
s[left] = s[right];
s[right] = mychar;
left++;
right--;
}
}
}
没有必要输出,只要程序执行结束,
时间复杂度:O(N),其中 NN 为字符数组的长度。一共执行了 N/2N/2 次的交换。
空间复杂度:O(1)。只使用了常数空间来存放若干变量。
题目:541. 反转字符串II
问题描述
给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例:
输入: s = “abcdefg”, k = 2
输出: “bacdfeg”
思路
其实在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
因为要找的也就是每2 * k 区间的起点,这样写程序会高效很多。
「所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。」
解法
class Solution {
public String reverseStr(String s, int k) {
char[] charArray = s.toCharArray();
for (int start=0;start<charArray.length-1;start = start + 2*k){
int i=start ; int j =Math.min(start+k-1,charArray.length -1);
while (i < j){
char temp = charArray[i];
charArray[i]=charArray[j]; i++;
charArray[j]=temp; j--;
}
}
return new String(charArray); // 用toString()会有空指针风险,用+""不优美
}
}
这样写更容易看懂,就是交换元素之后,移动两个指针
class Solution {
public String reverseStr(String s, int k) {
char[] charArray = s.toCharArray();
for (int start=0;start<charArray.length-1;start = start + 2*k){
int i=start ; int j =Math.min(start+k-1,charArray.length -1);
while (i < j){
char temp = charArray[i];
charArray[i]=charArray[j];
charArray[j]=temp;
i++;
j--;
}
}
return new String(charArray); // 用toString()会有空指针风险,用+""不优美
}
}
可以向上面一样,写成一个for循环,如下:
class Solution {
public String reverseStr(String s, int k) {
char[] charArray = s.toCharArray();
for (int start=0;start<charArray.length-1;start = start + 2*k){
for(int i=start,j =Math.min(start+k-1,charArray.length -1);i < j;i++,j--){
char temp = charArray[i];
charArray[i]=charArray[j];
charArray[j]=temp;
}
}
return new String(charArray); // 用toString()会有空指针风险,用+""不优美
}
}
int j =Math.min(start+k-1,charArray.length -1);
三种情况,如果剩余元素大于2k,j=start+k-1,
如果剩余元素大于k小于2k,j=start+k-1,
如果剩余元素小于k,j=a.length-1,此时,还是满足 i<j ,可以进入while循环
关于while(i<j)循环体
leetcode206,反转链表
问题描述
反转链表(头插法+改变指针指向)
class Solution {
public ListNode reverseList(ListNode head) {
ListNode first = new ListNode(-1); // 新建一个虚拟头节点
first.next=null; // 并设置next为null,这里是为了使用代码对称,其实不设置这个也可以
ListNode cur=head; // p执行指向原链表实际头结点
while(cur!=null){
ListNode temp = cur.next; // 因为下面要修改cur.next,所以暂存cur.next
cur.next = first.next;
first.next = cur;
cur=temp; // while循环中最后一句就是实现指针cur的移动
}
return first.next; // first本身这个元素不要(就是val为-1的这个)
}
}
关于返回值:这里最后的first.next是指向第一个实体头结点的。
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur=head;
ListNode pre=null;
while(cur!=null){
ListNode temp = cur.next; // 保存一下 cur的下一个节点,因为接下来要改变cur->next
cur.next = pre; // 这里就是翻转操作,pre里面存放着上一个元素(因为cur曾经指向上一个元素,又pre=cur),cur操作当前所指向的链表元素的next指针变为指向上一个元素,
// 更新pre 和 cur指针
pre = cur;
cur = temp; // while循环中最后一句就是实现指针cur的移动
}
return pre;
}
}
关于返回值:最后的pre是指向最后一个元素的,而此时链表所有的next指针都反转过来了,所以pre指向的就是第一个实体头结点。
题目:151,反转字符串里的单词(有空格的就是单词,所以必须识别空格)
解法(调用底层静态方法)
class Solution {
public String reverseWords(String s) {
s=s.trim(); // 先去掉字符串首尾空格,就仅仅剩下中间的空格了,
List list = Arrays.asList(s.split("\\s+")); // 数组类的静态方法,参数为数组,返回值为list
Collections.reverse(list); // Collection类的静态方法,参数为list,返回值为list
return String.join(" ",list); // String类的静态方法,参数为list,返回为String
}
}
小结:
先去掉字符串首尾空格,就仅仅剩下中间的空格了
然后按照中间的空格split,得到结果Arrays.asList变为一个List
然后对list中的每一个item元素进行反转
最后用String.join,将list中的各个元素使用空格连接起来
看题目,因为要反转的是整个句子中的各个单词,而不是每个单词中的各个字符,所以就放到list中
public String[] split(String regex)根据给定的正则表达式的匹配来拆分此字符串。正则表达式中,
\s表示 空格,回车,换行等空白符,
+号表示一个或多个的意思
split("\s+") 按空格,制表符,等进行拆分(也就是说它是按空白部分进行拆分,不管这个空白使用设么操作留下的,比如空格键、tab键)
split(" +") 按空格进行拆分(也就是说只有按空格键流出来的空白才会是拆分的一句)
String.join()方法是JDK1.8之后新增的一个静态方法,使用方式如下所示:
String result = String.join("-",“a”,“b”,“c”,“d”);
输出结果如下:a-b-c-d
也可使用如下方式:
String[] arr = {“a”,“b”,“c”,“d”};
String result = String.join("-",arr);
输出结果如下:a-b -c-d
参数列表:
1、表示连接的符号
2、表示被连接的数组(也可以是集合),或者是要连接的多个字符串
四个函数用自己的代码表述(实际上就是抄开源代码)
如下: