Code Capriccio brush questions - string

Posted by nads1982 on Sun, 23 Jan 2022 23:47:10 +0100

This article is a note taken when writing questions with the code Capriccio every day, which is used to summarize and review.

catalogue

344. Reverse string

541. Reverse string II

Sword finger offer 05 Replace spaces

151. Reverse the words in the string

Sword finger offer 58 - Ⅱ Left rotation string

28. Implement str ()

459. Duplicate substring

Today's summary

344. Reverse string

Title Link: 344. Reverse string - LeetCode (LeetCode CN. Com)

Idea: the idea is very simple, that is, a double pointer plus element exchange

 public void reverseString(char[] s) {
        int left = 0;
        int right = s.length - 1;
        while (left < right){
            char temp = s[left];
            s[left++] = s[right];
            s[right--] = temp;
        }
    }

541. Reverse string II

Title Link: 541. Reverse string II - LeetCode (LeetCode CN. Com)

Idea: invert the string of 0 + (2 * k) * i ~ (k - 1) + (2 * k) * i subscript within the string length range, and the value of i is 0, 1, 2, 3, Note that you can judge the case that the length exceeds the string length.

public String reverseStr(String s, int k) {
        char[] chars = s.toCharArray();
        int left = 0;
        int right = left + k - 1;
        if (right >= chars.length){
            right = chars.length - 1;
        }
        while (right < chars.length){
            int fLeft = left;
            int fRight = right;
            while (fLeft < fRight){
                char temp = chars[fLeft];
                chars[fLeft++] = chars[fRight];
                chars[fRight--] = temp;
            }
            left += 2 * k;
            right += 2 * k;
            if (left >= chars.length){
                break;
            }
            if (right >= chars.length){
                right = chars.length - 1;
            }
        }

        return new String(chars);
    }

Sword finger offer 05 Replace spaces

Title Link: Sword finger Offer 05 Replace space - LeetCode (LeetCode CN. Com)

Idea:

① : directly use the replace method in String

    public String replaceSpace(String s) {
        String s1 = s.replace(" ", "%20");
        return s1;
    }

② : do not use the solution of library function, use StringBuilder to splice strings to improve the speed

public String replaceSpace(String s) {
        StringBuilder str = new StringBuilder();
        for(int i = 0 ; i < s.length(); i++){
            char ch = s.charAt(i);
            if(ch == ' '){
                str.append("%20");
            } 
            else{
                str.append(ch);
            } 
        }
        return str.toString();
}

③ : normal solution: first expand the length of the String to the length after replacement. Here, use StringBuilder to expand it, because String is immutable. Set two pointers, one to the end of the String before expansion (bf) and the other to the end of the String after expansion (af). Use bf to traverse the String from front to back. If spaces are found, use af to store "% 20". If no spaces are found, use af to store bf corresponding characters

public String replaceSpace(String s){
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' '){
                count++;
            }
        }
        StringBuilder stringBuilder = new StringBuilder(s);
        for (int i = 0; i < count; i++) {
            stringBuilder.append("  ");
        }
        String str = stringBuilder.toString();
        char[] chars = str.toCharArray();
        int bf = s.length() - 1;
        int af = stringBuilder.length() - 1;
        while (bf >= 0){
            if (chars[bf] == ' '){
                chars[af--] = '0';
                chars[af--] = '2';
                chars[af--] = '%';
                bf--;
            }else {
                chars[af--] = chars[bf--];
            }
        }
        return new String(chars);
    }

151. Reverse the words in the string

Title Link: 151. Flip the word in the string - LeetCode (LeetCode CN. Com)

Idea:

① : use the split function in String to get each word and splice the words

public String reverseWords(String s) {
        String[] s1 = s.split(" ");
        StringBuilder str = new StringBuilder();
        int flag = 0;
        while (s1[flag].equals("")){
            flag++;
        }
        for (int i = s1.length - 1;  i > flag; i--) {
            if (!s1[i].equals("")){
                str.append(s1[i]);
                str.append(" ");
            }
        }
        str.append(s1[flag]);
        return str.toString();
    }

② : do not use library functions: first remove the spaces at the beginning and end of the string, then reverse the string and deal with the middle spaces, as follows

Original string:

Processed string:  

Finally, use the space as a sign to get each word, and then reverse each word

public String reverseWords(String s) {
        char[] chars = s.toCharArray();
        int left = 0;
        int right = chars.length - 1;
        StringBuilder newStr = new StringBuilder();
        //Remove leading and trailing spaces
        while (left <= right){
            if (chars[left] == ' '){
                left++;
            }
            if (chars[right] == ' '){
                right--;
            }
            if (chars[left] != ' ' && chars[right] != ' '){
                break;
            }
        }
        //Reverse the string order and handle the middle space
        int bfRight = right - 1;
        while (right > left){
            if (chars[right] != ' ' || (chars[right] == ' ' && chars[bfRight] != ' ')){
                newStr.append(chars[right]);
            }
            right--;
            bfRight--;
        }
        newStr.append(chars[left]);
        getAndReverse(newStr);
        return newStr.toString();
    }
    //Get each word and reverse it
    public void getAndReverse(StringBuilder stringBuilder){
        int head = 0;
        int end = 0;
        while (end < stringBuilder.length()){
            if (stringBuilder.charAt(end) == ' '){
                reverse(stringBuilder, head, end - 1);
                head = end + 1;
            }
            end++;
        }
        reverse(stringBuilder, head, end - 1);
    }
    //Invert each word
    public void reverse(StringBuilder stringBuilder, int head, int end){
        while (head < end){
            char temp = stringBuilder.charAt(head);
            stringBuilder.setCharAt(head, stringBuilder.charAt(end));
            stringBuilder.setCharAt(end, temp);
            head++;
            end--;
        }
    }

Sword finger offer 58 - Ⅱ Left rotation string

Title Link: Sword finger Offer 58 - II Left rotation string - LeetCode (LeetCode CN. Com)

Idea:

① : intercept the corresponding substring for splicing

public String reverseLeftWords(String s, int n){
        StringBuilder ansStr = new StringBuilder();
        ansStr.append(s.substring(n, s.length()));
        ansStr.append(s.substring(0, n));
        return ansStr.toString();
    }

② : invert the whole string first, and then the corresponding substring

 public String reverseLeftWords(String s, int n){
        StringBuilder ansStr = new StringBuilder(s);
        int length = ansStr.length();
        reverse(ansStr, 0, length - 1);
        reverse(ansStr, 0, length - n - 1);
        reverse(ansStr, length - n, length - 1);
        return ansStr.toString();
    }
    public void reverse(StringBuilder stringBuilder, int head, int end){
        while (head < end){
            char temp = stringBuilder.charAt(head);
            stringBuilder.setCharAt(head, stringBuilder.charAt(end));
            stringBuilder.setCharAt(end, temp);
            head++;
            end--;
        }
    }

28. Implement str ()

Title Link: 28. Implement strStr() - LeetCode (LeetCode CN. Com)

Idea:

① : Horspool algorithm: set a move table. The setting rules are shown in the figure below. Move it against the move table according to the different conditions of the character c corresponding to the end of the haystack string and the need string when the matching is unsuccessful.

 

public int strStr(String haystack, String needle) {
        if (needle.length() == 0){
            return 0;
        }
        Map<Character, Integer> move = new HashMap<>();
        int flag = needle.length() - 1;
        int count = 0;
        if (needle.length() > 1){
            while (flag > 0){
                flag--;
                count++;
                if (!move.containsKey(needle.charAt(flag))){
                    move.put(needle.charAt(flag), count);
                }
            }
        }
        int hayPo = needle.length() - 1;
        while (hayPo < haystack.length()){
            int nePo = needle.length() - 1;
            int moveHayPo = hayPo;
            while (needle.charAt(nePo) == haystack.charAt(moveHayPo)){
                nePo--;
                moveHayPo--;
                if (nePo < 0){
                    return moveHayPo + 1;
                }
            }
            if (move.containsKey(haystack.charAt(hayPo))){
                hayPo += move.get(haystack.charAt(hayPo));
            }else {
                hayPo += needle.length();
            }
        }
        return -1;
    }

② : KMP algorithm: directly learn Kago's video:

Help you learn the KMP algorithm thoroughly! (Theory) bilibili bili

Help you learn the KMP algorithm thoroughly! (seeking the code of next array) bilibili bili

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

459. Duplicate substring

Title Link: 459. Repeated substring - LeetCode (LeetCode CN. Com)

Idea: kmp algorithm is also used. By analyzing the next array, it can be found that if the length of the string can be divided by subtracting the longest common prefix from the length of the string, it means that the string conforms to the meaning of the question (of course, it depends on the solution of the question) 😭😭😭)

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

Today's summary

The difficulty is the kmp algorithm, which needs to be understood more

 

Topics: Java Algorithm leetcode