1、344. 反转字符串
class Solution {
public void reverseString(char[] s) {
//使用左右指针,跟单链表的反转简单,单链表是反转过去
int left = 0,right = s.length-1;
// while(left<right)
for(int i=0;i<s.length/2;i++){
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
}
回顾链表反转
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head ==null || head.next ==null) return head;
ListNode cur = head;//当前节点
ListNode pre = null;//前驱节点
while(cur!=null){
ListNode temp = cur.next; //记录下一个节点的位置,防止找不到
cur.next = pre; //第一次pre为空,实现链表的端口操作
pre = cur; //前驱节点指向下一个
cur = temp; //当前节点指向临时存储的节点(下一个节点)
}
return pre; //返回pre节点,是因为pre节点已经指向最后一个位置了,各自的指针已经转变,并且此时cur为null。我错误的以为是head,其实head只指向1一个值了
}
}
2、541. 反转字符串 II
-
其实在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
-
因为要找的也就是每2 * k 区间的起点,这样写,程序会高效很多。
-
所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。
class Solution {
public String reverseStr(String s, int k) {
//交换使用左右指针
char[] ch = s.toCharArray();
//以2k位置为界,处理
//其实在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
for(int i=0;i<ch.length;i+=2*k){
int left = i;
//判断尾数够不够k个来取决right指针的位置
//假设 left =0,k=2,那么left + k - 1=1
//假设 left =2,k=2,那么left + k - 1=3
int right = Math.min(ch.length - 1,left + k - 1);
while(left<right){
char temp = ch[left];
ch[left]= ch[right];
ch[right] = temp;
left++;
right--;
}
}
return new String(ch);
}
}
3、剑指 Offer 05. 替换空格
class Solution {
public String replaceSpace(String s) {
//使用 sb 逐个复制 s ,碰到空格则替换,否则直接复制
StringBuilder str = new StringBuilder();
for(int i=0;i<s.length();i++){
if(s.charAt(i) == ' '){
str.append("%20");
}else{
str.append(s.charAt(i));
}
}
return str.toString();
}
}
4、151. 反转字符串中的单词
class Solution {
public String reverseWords(String s) {
/**
* 不使用Java内置方法实现
* <p>
* 1.去除首尾以及中间多余空格
* 2.反转整个字符串
* 3.反转各个单词
*/
// 1.去除首尾以及中间多余空格
StringBuilder sb = removeSpace(s);
// 2.反转整个字符串
reverseString(sb, 0, sb.length() - 1);
// 3.反转各个单词
reverseEachWord(sb);
return sb.toString();
}
// 1.去除首尾以及中间多余空格
private StringBuilder removeSpace(String s){
int start =0;
int end = s.length() -1;
while(s.charAt(start) == ' ') start++; //计算开头有多少个空格
while(s.charAt(end) == ' ') end--; //计算除去结尾的空格有多长
//计算出start和end的位置就是除去首位空格的
//接下来处理的是单词与单词之间的位置
StringBuilder sb = new StringBuilder();
while(start<=end){
char c = s.charAt(start);
//表示插入前一个位置不能为空 sb.charAt(sb.length() -1)!=' '
if(c!=' ' || sb.charAt(sb.length() -1)!=' '){
sb.append(c);
}
start++; //遇到空格跳过
}
return sb;
}
//反转整个字符串
private void reverseString(StringBuilder sb,int start,int end){
while(start<end){
char temp = sb.charAt(start);
sb.setCharAt(start,sb.charAt(end));
sb.setCharAt(end,temp);
start++;
end--;
}
}
//单个单词反转
private void reverseEachWord(StringBuilder sb){
int start = 0;
int end =1;
int n = sb.length();
while(start<n){
//找到空格
while(end<n&&sb.charAt(end)!=' '){
end++;
}
//反转
reverseString(sb,start,end-1);
start = end +1;
end = start +1;
}
}
}
5、剑指Offer58-II.左旋转字符串
class Solution {
public String reverseLeftWords(String s, int n) {
//偷懒做法 return s.substring(n) + s.substring(0,n);
//正确做法:
//[0,n),[n,s.length-1]翻转,最后全部翻转
StringBuilder sb = new StringBuilder(s);
reverseString(sb,0,n-1);
reverseString(sb,n,s.length()-1);
reverseString(sb,0,s.length()-1);
return sb.toString();
}
//翻转
private void reverseString(StringBuilder s,int start,int end){
while(start<end){
char temp = s.charAt(start);
s.setCharAt(start,s.charAt(end));
s.setCharAt(end,temp);
start++;
end--;
}
}
}