代码随想录算法训练营第八天 | LeetCode 344.反转字符串 541. 反转字符串II 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转字符

一、 LeetCode 344.反转字符串

1. 题目链接

LeetCode344.反转字符串

2. 学习资料:
3. 思路
  1. 和反转链表的思想一样,也是用双指针
  2. 写一个交换函数
  3. 左指针指向数组的初始位置,右指针指向数组的末位索引位置
  4. 每次交换完成左指针++,右指针–。
  5. 当左指针的值 > =右指针的值时停止循环。
4. 代码
class Solution {
    public void reverseString(char[] s) {
        int left =0;
        int right = s.length-1;
        while(left<right){
            swap(s,left,right);
            left++;
            right--;
        }

    }
    public void swap(char[]s,int index1 ,int index2){
        char temp = s[index1];
        s[index1] = s[index2];
        s[index2] = temp;
    }
}

二、 LeetCode 541. 反转字符串II

1. 题目链接

LeetCode541. 反转字符串II

2. 学习资料:
3. 思路
4. 代码
class Solution {
    //题目的意思其实概括为 每隔2k个反转前k个,尾数不够k个时候全部反转
    public String reverseStr(String s, int k) {
        char[] c = s.toCharArray();
        for(int i=0;i<c.length;i+=2*k){
            int start = i;
            //判断尾数是否还有k个位置,来决定end指针的位置
            int end = Math.min(c.length-1,start+k-1);
            while(start < end){
                swap(c,start,end);
                start++;
                end--;
            }
        }
        return new String(c);
    }
    public void swap(char[] c, int index1,int index2){
        char temp = c[index1];
        c[index1] = c[index2];
        c[index2] = temp;
    }
}

三、 剑指Offer 05.替换空格

1. 题目链接

剑指Offer 05.替换空格

2. 学习资料:
3. 思路

此时算上本题,我们已经做了七道双指针相关的题目了分别是:

27.移除元素
15.三数之和
18.四数之和
206.翻转链表
142.环形链表II
344.反转字符串

4. 代码
class Solution {
    public String replaceSpace(String s) {
        if(s.length() == 0 || s == null){
            return s;
        }
        StringBuilder sb = new StringBuilder();
        //双指针法第一步,先扩容字符串长度大小,为空格数量的两倍
        for(int i =0; i < s.length();i++){
            if(s.charAt(i) == ' '){
                sb.append("  ");
            }
        }
        if(sb.length() == 0){
            return s;
        }
        int left = s.length()-1;
        s += sb.toString();
        int right = s.length()-1;
        char[] ch = s.toCharArray();
        while(left >= 0){
            if(ch[left] == ' '){
                ch[right--] = '0';
                ch[right--] = '2';
                ch[right] = '%';

            }else{
                ch[right] = ch[left];
            }
            right--;
            left--;
        }
        return new String(ch);
    }
}

四、 LeetCode 151.翻转字符串里的单词

1. 题目链接

LeetCode151.翻转字符串里的单词

2. 学习资料:
3. 思路
  1. 倒序遍历字符串,记录单词的左右索引为i,j
  2. 移动指针i,直到遇到空格停止,这时候 i+1 到 j 这个位置就是一个单词的位置了
  3. 将每一个单词加入到返回结果的变量中
4. 代码
class Solution {
    public String reverseWords(String s) {
    	//去除字符串首尾空格
        s = s.trim();
        int j = s.length()-1;
        int i = j;
        StringBuilder sb = new StringBuilder();
        while(i>=0){
        	//倒着查找单词的首字母,遇到空格说明这个位置的下一个位置就是后边单词的起始位置
            while(i>=0 && s.charAt(i) != ' '){
                i--;
            }
            //将单词添加进结果中
            sb.append(s.substring(i+1,j+1)+" ");
            //让i向前移动寻找下一个单词的末位字幕
            while(i>=0 && s.charAt(i) == ' '){
                i--;
            }
            //移动j指针到i处
            j=i;
        }
        return sb.toString().trim();
    }
}

五、 LeetCode 剑指Offer58-II.左旋转字符

1. 题目链接

剑指Offer58-II.左旋转字符

2. 学习资料:
3. 思路
  1. 先把整个字符串翻转
  2. 再翻转字符串从0到倒数第n个位置前一个位置
  3. 再翻转字符串从倒数第n个位置到最后
4. 代码
class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] ch = s.toCharArray();
        //先把整个字符串翻转
        reverse(ch,0,ch.length-1);
        //再翻转字符串从0到倒数第n个位置的前一个位置
        reverse(ch,0,ch.length-1-n);
        //再翻转字符串从倒数第n个位置到最后
        reverse(ch,ch.length-n,ch.length-1);
        return new String(ch);

    }
    //这里的两个值的交换很有意思,都不需要用一个额外变量了
    // 举个例子 a^b a异或b会得到一个值 -> a^b
    // a^b 这个值再异或一下b 也就是 a^b^b, 这个值是a 因为一个数和自己异或就会变为0
    // 但是任何数和0进行异或运算得出的值还是自己 因此 a^b^b这个操作的最终结果变回了a
    //因此我们用了这个异或运算的原理,可以进行两个数的交换
    public void reverse(char[] s,int left,int right){
        while(left<right){
            s[left] ^= s[right];
            s[right] ^= s[left];
            s[left] ^= s[right];
            left++;
            right--;
        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值