Leet code 541.反转字符串II

题目描述

给定一个字符串s和一个整数k,从字符串开头算起,每计数至2k个字符,就反转这2k字符串中的前k个字符串。

  • 如果剩余字符少于k个,则全部反转
  • 如果剩余字符小于2k个但大于等于k个,则反转向k个字符,其余字符保持原样

思路讲解

int lop = length / (2*k);
将字符串以2k个字符一组,分成lop组
每循环一次就是处理一组字符
start 是每一组的处理字符的起始下标
end 是每一组的处理字符的结束下标
通过自定义的子方法是用来处理指定区域的的字符串反转

因为处理的字符串不一定都是2k的倍数所我们需要根据题目定的规则来片时剩余的字符
使用diff变量来表示剩余的字符数量

代码实现

class Solution {
    public String reverseStr(String s, int k) {
        char[] chars = s.toCharArray();
        int length = chars.length;
        int lop = length / (2*k);
        int i = 0;
        for (i = 0; i < lop; i++) {
            int start = i*2*k;
            int end = start+k-1;
            s = reverseAreaStr(s,start,end);
        }
        int diff = s.length() - (i*2*k);
        if (diff == 0) {
            return s;
        } else if (diff < k) {
            return reverseAreaStr(s,i*2*k,s.length()-1);
        } else {
            return reverseAreaStr(s,i*2*k,i*2*k+k-1);
        }
    }
    public String reverseAreaStr(String s,int start ,int end) {
        char[] chars = s.toCharArray();
        if ( start >= end || start < 0 || end >= chars.length) {
            return s;
        }
        //System.out.println("----");
        char temp;
        for (int i = 0; i<=(end-start)/2; ++i) {
            temp = chars[start+i];
            chars[start+i] = chars[end-i];
            chars[end-i] = temp;
        }
        return new String(chars);
    }
}

代码实现细节

end = start + k -1 每次从start位置开始的k的字符进行处理,因为start也算是一个字符,start+1是我们处理的第二个字符,按照这个规律 start + n 是处理的第start + n + 1个字符,我们要处理到k个字符下标应该是 start + k -1
reverseAreaStr(s,i*2*k,i*2*k+k-1)中的i*2*k+k-1根上面也是同一原理。

总结

通过这个算法更理解了子串的某一区域的上下界限如何定位。我们在处理字符串的某一子串进行反转时,要先确定区域的上界和区域的下界,然向中间移动。如果对全部的字符串进行反转,这个上界就是字符串长度减一,下界是0。反转时需要移动的次数,应该根据反转字符数量决定,因为是一次操作两个字符,所以循环次数应该除2。
计算反转次数时
如果是全部字符串 循环次数是(len - 0)/ 2 可以等价为 len / 2
如果是子串 循环次数是 (end - start) / 2

posted @ 2022-11-16 19:11  wzpro  阅读(35)  评论(0)    收藏  举报