算法刷题笔记08 | 第四章 字符串P1 | 344. 反转字符、541. 反转字符II、剑指05、151. 翻转字符串里的单词、剑指58-II

344 反转字符串

这题是这天几乎所有的基础,难度较低 思路:建立头尾指针,两两交换 代码:

public void reverseString(char[] s) {
    int head = 0;
    int tail = s.length - 1;

    while (tail > head){
        char temp = s[tail];
        s[tail] = s[head];
        s[head] = temp;
        tail--;
        head++;
    }

}

541 反转字符串Ⅱ

方式一 无脑暴力硬写

public String reverseStr(String s, int k) {
    char[] arr = s.toCharArray();
    int head = 0;
    int tail = 0;
    // 冲突问题:k元素过大
    // 1.当head已经指向最后元素,不能在再交换
    // 2.当剩余不够2k但足够k
    // 3.当剩余不够k
    while (arr.length - 1 > tail) {
        tail++;

        if ((tail + 1) % (2 * k) == 0 || tail == arr.length - 1) {
            // 交换前k个元素
            // 避免k > length的情况
            int head2 = Math.min(head + k - 1,arr.length - 1);

            if (head == arr.length - 1) continue;
            // 344 - 反转字符串
            while (head2 > head) {
                char temp = arr[head];
                arr[head] = arr[head2];
                arr[head2] = temp;
                head2--;
                head++;
            }
            head = tail + 1;
        }
    }

    return new String(arr);
}

方式二  带脑子仔细思考 for循环,结合了while的条件以及最初的tail++,此写法的i = i + 2*k更优化时间复杂度

public String reverseStr(String s, int k) {
    char[] arr = s.toCharArray();
    for (int i = 0; i < arr.length; i = i + 2*k) {
        int head = i;
        // 避免k > length的情况
        int tail = Math.min(arr.length - 1,head + k - 1);
        // 344 - 反转字符串
        while (tail > head){
            char temp = arr[head];
            arr[head] = arr[tail];
            arr[tail] = temp;

            tail--;
            head++;
        }
    }
    return new String(arr);

}

剑指Offer 05.替换空格

难度较低 思路:遍历数组,有空格就替换(使用StringBuffer操作字符串)

public String replaceSpace(String s) {
    if (s == null) return null;
StringBuffer sb = new StringBuffer();

for (int i = 0; i < s.length(); i++) {
    if (s.charAt(i) == ' '){
        sb.append("%20");
    }
    else {
        sb.append(s.charAt(i));
    }
}

return sb.toString();

}

151.翻转字符串里的单词

思路:

  • 去掉多余空格(首尾 单词间)
  • 反转字符串
  • 翻转单词
public String reverseWords(String s) {
    /*
* 思路:
* 1. 去掉多余空格(首尾 单词间)
* 2, 反转字符串
* 3, 翻转单词
* */

    // 1. 去除空格
    StringBuffer sb = removeSpace(s);
// 2. 反转字符串
reverseString(sb,0,sb.length() - 1);
// 3. 反转单词
reverseWord(sb);
return sb.toString();
}

// 功能:去除多余空格
public StringBuffer removeSpace(String s) {
    // 去除首尾空格
    int start = 0;
    int end = s.length() - 1;
    while (s.charAt(start) == ' ') start++;
    while (s.charAt(end) == ' ') end--;

    // 返回
    StringBuffer sb = new StringBuffer();
    while (end >= start) {
        char c = s.charAt(start);
        // 去除单词间多余空格
        // 条件一:记录单词 条件二:记录空格
        if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
            sb.append(c);
        }
        start++;
    }
    return sb;
}

// 功能:344 - 反转字符串
public void reverseString(StringBuffer sb, int start, int end) {
    while (end >= start) {
        char c = sb.charAt(end);
        sb.setCharAt(end,sb.charAt(start));
        sb.setCharAt(start,c);
        start++;
        end--;
    }
}

// 功能:反转单词
public void reverseWord(StringBuffer sb){
    int start = 0;
int end = 1;

// 遍历整个句子
while (start < sb.length()){
    // 寻找一个单词
    while (end < sb.length() && sb.charAt(end)!=' '){
        end++;
    }
    // 找到后 344 - 反转字符串(不反转空格)
    reverseString(sb,start,end - 1);
    start = end + 1;
    end = start + 1;
}

}

剑指Offer58-II.左旋转字符串

思路:“负负得正”

  • 先把前n个和后面元素分别反转,自然形成两组[-1,-2],然后全部一起反转变成[2,1],前n个数自然跑到后面
public String reverseLeftWords(String s, int n) {
    // 思路:负负得正
    // 先把前n个和后面元素分别反转,自然形成两组[-1,-2],然后全部一起反转变成[2,1],前n个数自然跑到后面

    int len = s.length();
    StringBuilder sb = new StringBuilder(s);
    reverseString(sb, 0, n - 1);

    reverseString(sb, n, len - 1);

    return sb.reverse().toString();
}

public 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--;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值