电信保温杯笔记——代码随想录 刷题攻略 字符串

电信保温杯笔记——代码随想录 刷题攻略 字符串

  • 电信保温杯笔记——代码随想录 刷题攻略
  • 1.字符串:这道题目,使用库函数一行代码搞定
    • 344.反转字符串
  • 2.字符串:简单的反转还不够!
    • 541. 反转字符串II
  • 3.字符串:替换空格
    • 剑指Offer 05.替换空格
  • 4.字符串:花式反转还不够!
    • 151.翻转字符串里的单词
  • 小结
  • 5.字符串:反转个字符串还有这个用处?
    • 剑指Offer58-II.左旋转字符串
  • 6.帮你把KMP算法学个通透
    • 28. 实现 strStr()
      • 方式1:暴力实现
      • 方式2:KMP
      • 小结
  • 7.字符串:KMP算法还能干这个!
    • 459.重复的子字符串
  • 字符串:总结篇!

电信保温杯笔记——代码随想录 刷题攻略

代码随想录 刷题攻略
电信保温杯笔记——代码随想录 刷题攻略

1.字符串:这道题目,使用库函数一行代码搞定

讲义地址

344.反转字符串

leetcode地址

class Solution {
    public void reverseString(char[] s) {
        if(s == null || s.length < 2) return;
        int left = 0;
        int right = s.length -1;
        while (left < right){
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
}

电信保温杯笔记——代码随想录 刷题攻略 字符串_第1张图片

2.字符串:简单的反转还不够!

讲义地址

541. 反转字符串II

leetcode地址

class Solution {
    public String reverseStr(String s, int k) {
        char[] temp = s.toCharArray();
        int len = s.length();
        int loop = len / (2*k);
        int residue = len % (2*k);
        for (int i = 0; i < loop; i++) {
            reverseString(temp, i*2*k, i*2*k+k-1);
        }
        if (residue < k){
            reverseString(temp, loop*2*k, len-1);
        }else {
            reverseString(temp, loop*2*k, loop*2*k+k-1);
        }
        return new String(temp);
    }

    public void reverseString(char[] s, int left, int right) {
        if(s == null || right-left < 1) return;
        while (left < right){
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
}

电信保温杯笔记——代码随想录 刷题攻略 字符串_第2张图片

3.字符串:替换空格

讲义地址

剑指Offer 05.替换空格

leetcode地址

class Solution {
    public String replaceSpace(String s) {
        StringBuilder res = new StringBuilder();
        for(Character c : s.toCharArray())
        {
            if(c == ' ') res.append("%20");
            else res.append(c);
        }
        return res.toString();
    }
}

电信保温杯笔记——代码随想录 刷题攻略 字符串_第3张图片
使用StringBuilder效率比String高

4.字符串:花式反转还不够!

讲义地址

151.翻转字符串里的单词

leetcode地址

class Solution {
    /**
     * 不使用Java内置方法实现
     * 

* 1.去除首尾以及中间多余空格 * 2.反转整个字符串 * 3.反转各个单词 */ public String reverseWords(String s) { // System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]"); // 1.去除首尾以及中间多余空格,并反转整个字符串 StringBuilder sb = removeSpace(s); // 2.反转各个单词 reverseEachWord(sb); return sb.toString(); } private StringBuilder removeSpace(String s) { // System.out.println("ReverseWords.removeSpace() called with: s = [" + s + "]"); int start = 0; int end = s.length() - 1; while (s.charAt(start) == ' ') start++; while (s.charAt(end) == ' ') end--; StringBuilder sb = new StringBuilder(); // 倒序收集,即反转整个字符串 while (start <= end) { char c = s.charAt(end); if (c != ' ' || // 上一个收集的字符不为空格 sb.charAt(sb.length() - 1) != ' ') { sb.append(c); } end--; } // System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]"); return sb; } /** * 反转字符串指定区间[start, end]的字符 */ public void reverseString(StringBuilder sb, int start, int end) { // System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]"); while (start < end) { char temp = sb.charAt(start); sb.setCharAt(start, sb.charAt(end)); sb.setCharAt(end, temp); start++; end--; } // System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]"); } 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; } } }

电信保温杯笔记——代码随想录 刷题攻略 字符串_第4张图片

小结

翻转字符串的核心代码就是题目344的代码。

5.字符串:反转个字符串还有这个用处?

讲义地址

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

leetcode地址

class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuilder sb = new StringBuilder();
        for (int i = n; i < s.length(); i++) {
            sb.append(s.charAt(i));
        }
        for (int i = 0; i < n; i++) {
            sb.append(s.charAt(i));
        }
        return sb.toString();
    }
}

电信保温杯笔记——代码随想录 刷题攻略 字符串_第5张图片

6.帮你把KMP算法学个通透

讲义地址

28. 实现 strStr()

leetcode地址

方式1:暴力实现

class Solution {
    public int strStr(String haystack, String needle) {
//        if (needle == "") return 0; 不能这样写,
//        因为String类指向堆空间,堆空间再指向方法区中
//        的字符串,这样写会地址不一样而出错
        if (needle.length() == 0) return 0;
        int len_h = haystack.length();
        int len_n = needle.length();
        if (len_h < len_n) return -1;
        int left = 0;
        int right = 0;
        while (left < len_h){
            for (int i = 0; i < len_n; i++) {
                if (haystack.charAt(right) != needle.charAt(i)){
                    break;
                }
                // needle遍历了一次,找到时长度刚好等于needle的长度
                if (right - left + 1 == len_n){
                    return left;
                }
                right++;
            }
            left++;
            right = left;
            // 剩余长度达不到needle的长度
            if (len_h - len_n < right){
                break;
            }
        }
        return -1;
    }
}

电信保温杯笔记——代码随想录 刷题攻略 字符串_第6张图片

方式2:KMP

class Solution {
    //前缀表(不减一)Java实现
    public int strStr(String haystack, String needle) {
        if (needle.length() == 0) return 0;
        int[] next = new int[needle.length()];
        getNext(next, needle);

        int j = 0;
        for (int i = 0; i < haystack.length(); i++) {
            while (j > 0 && needle.charAt(j) != haystack.charAt(i)) 
                j = next[j - 1];
            if (needle.charAt(j) == haystack.charAt(i)) 
                j++;
            if (j == needle.length()) 
                return i - needle.length() + 1;
        }
        return -1;

    }
    
    private void getNext(int[] next, String s) {
        int j = 0;// j:前缀尾部 and 前缀的长度
        next[0] = 0;
        for (int i = 1; i < s.length(); i++) {
        	// i:后缀尾部
            while (j > 0 && s.charAt(j) != s.charAt(i)) 
                j = next[j - 1];
            if (s.charAt(j) == s.charAt(i)) 
                j++;
            next[i] = j; 
        }
    }
}

电信保温杯笔记——代码随想录 刷题攻略 字符串_第7张图片

小结

getNext函数中,j = next[j - 1] 难以理解,j 回退到下一次比较的起始位置。

7.字符串:KMP算法还能干这个!

讲义地址

459.重复的子字符串

leetcode地址

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int len = s.length();
        if (len == 0 || len == 1) {
            return false;
        }

        int[] next = new int[len];
        getNext(next, s);
        if (next[len -1] != 0 && len % (len - next[len -1]) == 0){
            return true;
        }
        
        return false;
    }
    public void getNext(int[] next, String s){
        int j = 0;
        next[0] = 0;
        for (int i = 1; i < s.length(); i++) {
            while (j>0 && s.charAt(j) != s.charAt(i)){
                j = next[j-1];
            }
            if (s.charAt(j) == s.charAt(i)){
                j++;
            }
            next[i] = j;
        }
    }
}

电信保温杯笔记——代码随想录 刷题攻略 字符串_第8张图片
对于"abcabcabcabc",它的next数组为:
电信保温杯笔记——代码随想录 刷题攻略 字符串_第9张图片

字符串:总结篇!

讲义地址

你可能感兴趣的:(算法与数据结构,leetcode,算法,深度优先)