【代码随想录】-字符串专栏(Java)

反转字符串 leetcode-344

for (int i = 0, j = s.length - 1; i <= j; i++, j--) {
    char temp = s[i];
    s[i] = s[j];
    s[j] = temp;
}

反转字符串II leetcode-541

public String reverseStr(String s, int k) {
    int len = s.length();
    char[] charS = s.toCharArray();
    int start,end;
    for (int i = 0; i < charS.length; i+=2*k) {
        start = i;
        if(i + k > len){
            end = charS.length-1;
        }else {
            end = i + k-1;
        }
        reverse(charS,start,end);
    }
    return new String(charS);
}

public char[] reverse(char[] s,int i,int j){
    for (;i <= j; i++, j--) {
        char temp = s[i];
        s[i] = s[j];
        s[j] = temp;
    }
    return s;
}

剑指 Offer 05. 替换空格

/**
     * 剑指Offer 05.替换空格
     *
     * @param s
     * @return
     */
public String replaceString(String s) {
    if(s == null ) return null;
    StringBuilder sb = new StringBuilder();
    char[] chars = s.toCharArray();
    for (int i = 0; i < chars.length; i++) {
        if(chars[i] == 32){
            sb.append("%20");
        }else{
            sb.append(chars[i]);
        }
    }
    return sb.toString();
}

翻转字符串里的单词 leetcode-151

方法1:

/**
     * 暴力法,时间复杂度太高
     *
     * @param s
     * @return
     */
public String reverseWords2(String s) {
    s = s.trim(); //去除首尾空格
    List<StringBuilder> list = new ArrayList<>();
    char[] chars = s.toCharArray();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < chars.length; i++) {
        if (chars[i] == 32) {
            if (!sb.toString().equals("")) {
                list.add(sb);
            }
            sb = new StringBuilder("");
        } else {
            sb.append(chars[i]);
        }
    }
    list.add(sb);
    for (int i = 0, j = list.size() - 1; i < j; i++, j--) {
        StringBuilder temp = list.get(i);
        list.set(i, list.get(j));
        list.set(j, temp);
    }
    String res = "";
    for (int i = 0; i < list.size(); i++) {
        res += list.get(i).toString() + " ";
    }
    return res.trim(); //末尾多了一个空格
}

方法2:

public String reverseWords(String s) {
    //首先去除多余的空格
    //再反转整个字符串
    //最后单个单词进行反转
    StringBuilder sb = removeSpace(s);
    char[] chars = reverseString(sb.toString().toCharArray(), 0, sb.length() - 1);
    reverseEachWord(chars);
    return new String(chars);
}

/**
     * 反转每个单词
     *
     * @param chars
     */
public void reverseEachWord(char[] chars) {
    int start = 0, end = 1;
    while (start < chars.length){
        while (end < chars.length && chars[end] != ' ') {
            end++;
        }
        reverseString(chars, start, end-1);
        start = end + 1;
        end = start + 1;
    }
}

/**
     * 去除多余空格
     *
     * @param s
     * @return
     */
public StringBuilder removeSpace(String s) {
    //s.trim();
    int start = 0;
    int end = s.length() - 1;
    char[] chars = s.toCharArray();
    while (chars[start] == 32) start++;
    while (chars[end] == 32) end--;
    StringBuilder sb = new StringBuilder();
    int space = 0; //空格数量
    for (int i = start; i <= end; i++) {
        if (chars[i] != ' ') {  //在这里防止同时出现两个空格的情况
            sb.append(chars[i]);
            space = 0;
        } else {
            space++;
            if (space <= 1) {
                sb.append(chars[i]);
            }
        }
    }
    return sb;
}


/**
     * 反转整个字符串
     *
     * @param s
     * @param i
     * @param j
     * @return
     */
public char[] reverseString(char[] s, int i, int j) {
    for (; i <= j; i++, j--) {
        char temp = s[i];
        s[i] = s[j];
        s[j] = temp;
    }
    return s;
}

剑指 Offer 58 - II. 左旋转字符串

方法1:不申请额外空间,在自身操作

/**
     * 剑指 Offer 58 - II. 左旋转字符串
     * @param s
     * @param n
     * @return
     */
public String reverseLeftWords2(String s, int n) {
    //整个字符串反转
    char[] chars = s.toCharArray();
    reverseString(chars,0,chars.length-1);
    //反转前length-n个
    reverseString(chars,0,chars.length-n-1);
    //反转后n个
    reverseString(chars,chars.length-n,chars.length-1);
    return new String(chars);
}

public char[] reverseString(char[] s, int i, int j) {
    for (; i <= j; i++, j--) {
        char temp = s[i];
        s[i] = s[j];
        s[j] = temp;
    }
    return s;
}

方法2:速度快

public String reverseLeftWords(String s, int n) {
    String s1 = s.substring(0,n);
    String s2 = s.substring(n); //左闭右开
    StringBuffer sb = new StringBuffer();
    sb.append(s2).append(s1);
    return sb.toString();
}

实现 strStr() leetcode-28

方法1,暴力法:

/**
     * 28. 找出字符串中第一个匹配项的下标
     *
     * @param haystack
     * @param needle
     * @return
     */
public int strStr(String haystack, String needle) {
    char[] pattern = haystack.toCharArray();
    char[] str = needle.toCharArray();

    for (int i = 0; i <= pattern.length - str.length; i++) {
        int index = i;
        int j;
        for (j = 0; j < str.length; j++) {
            if (pattern[index++] != str[j]) {
                break;
            }
        }
        if (j == str.length) {
            return i;
        }
    }
    return -1;
}

方法2,kmp:

public int strStr2(String haystack, String needle) {
    char[] pattern = haystack.toCharArray();
    char[] str = needle.toCharArray();
    int[] next = getNext(needle);
    // System.out.println(Arrays.toString(next));
    for (int i = 0, j = 0; i < pattern.length;i++ ) {

        while (j > 0 && pattern[i] != str[j]) {
            j = next[j - 1];
        }
        if ( pattern[i] == str[j]) {
            j++;
        }
        if (j == str.length) return i - str.length + 1;
    }
    return -1;
}

//获取到一个字符串(子串) 的部分匹配值表
public int[] getNext(String s) {
    int[] next = new int[s.length()];
    next[0] = 0;
    for (int i = 1, j = 0; i < s.length(); i++) {
        while (j > 0 && s.charAt(i) != s.charAt(j)) {
            j = next[j - 1]; //回退
        }
        if (s.charAt(i) == s.charAt(j)) {
            j++;
        }
        next[i] = j;
    }
    return next;
}

重复的子字符串 leetcode-459

常规解法:

/**
     * 459. 重复的子字符串
     *
     * @param s
     * @return
     */
public boolean repeatedSubstringPattern(String s) {
    String str = s + s;
    if (str.substring(1, str.length() - 1).contains(s)) return true;
    return false;
}

kmp:

public boolean repeatedSubstringPattern(String s) {
    int[] next = getNext(s);
    // System.out.println(Arrays.toString(next));
    int len = s.length();
    //如果最后一个值有公共前后缀,满足可重复的话,next数组的最后一个值肯定是最大
    //并且len - next[len-1] 是一个周期  len对len - next[len-1] 取模肯定变为0
    if (next[len - 1] != 0 && len % (len - (next[len - 1] )) == 0) {
        return true;
    }
    return false;
}

public int[] getNext(String s) {
    int[] next = new int[s.length()];
    next[0] = 0;
    for (int i = 1, j = 0; i < s.length(); i++) {
        while (j > 0 && s.charAt(i) != s.charAt(j)) { //这里while和if都可以
            j = next[j - 1]; //回退
        }
        if (s.charAt(i) == s.charAt(j)) {
            j++;
        }
        next[i] = j;
    }
    return next;
}

你可能感兴趣的:(leetcode,java,leetcode,算法)