leetcode字符串刷题整理

使用的语言是java

题目344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:[“h”,“e”,“l”,“l”,“o”] 输出:[“o”,“l”,“l”,“e”,“h”]
示例 2:
输入:[“H”,“a”,“n”,“n”,“a”,“h”] 输出:[“h”,“a”,“n”,“n”,“a”,“H”]

思路:经典的数组前后交换操作,用一个temp存储临时值

class Solution {
    
    
    public void reverseString(char[] s) {
    
    
        int n = s.length;
        for (int i=0;i<n/2;i++) {
    
    
            char tmp = s[i];
            s[i] = s[n - 1 - i];
            s[n - 1 - i] = tmp;
        }
    }
}

题目541. 反转字符串II

给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。

如果剩余字符少于 k 个,则将剩余字符全部反转。

如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例:
输入: s = “abcdefg”, k = 2
输出: “bacdfeg”

思路:这个就是根据题目要求,多写一个for循环即可,注意在这里会涉及到字符串的替换
在有字符串多次替换,拼接,且中间生成的字符串没有用的情况下,建议使用Stringbuilder类
它是StringBuffer的线程不安全同义类,它负责在这里面进行字符串操作,且不污染字符串常量池

class Solution {
    
    
	//翻转char数组,并且将它转化为String
    public static String reverseString(char[] s) {
    
    
        int n = s.length;
        for (int i=0;i<n/2;i++) {
    
    
            char tmp = s[i];
            s[i] = s[n - 1 - i];
            s[n - 1 - i] = tmp;
        }
        return String.valueOf(s);
    }
    public String reverseStr(String s, int k) {
    
    
        int n= s.length();
	
		//格局题目要求写for循环
        StringBuilder sb = new StringBuilder(s);
        for (int i=0;i<n;i+=2*k){
    
    
            if (i+k>n) {
    
    
                char[] chars = s.substring(i,n).toCharArray();
                sb.replace(i,n,reverseString(chars));
            }else {
    
    
                char[] chars = s.substring(i, i + k).toCharArray();
                sb.replace(i, i + k, reverseString(chars));
            }
        }

        return sb.toString();
    }
}

题目剑指Offer 05.替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1:
输入:s = “We are happy.”
输出:“We%20are%20happy.”

思路:1.统计要替换的空格
2.计算输出字符串的长度
3.从后往前填充输出字符串,使用双指针法

class Solution {
    
    
    public String replaceSpace(String s) {
    
    
    	//统计空格个数
        char c = ' ';
        String replaceStr = "%20";
        char[] chars = s.toCharArray();
        int count = 0;
        for (int i=0;i<s.length();i++){
    
    
            if (chars[i] == c){
    
    
                count++;
            }
        }
		//生成输出字符串数组
        char[] newChars = new char[(replaceStr.length()-1)*count +chars.length];
        int j = newChars.length-1;
        //从后向前替换字符串,使用双指针法,i是前面的指针,j是后面的
        for (int i=s.length()-1;i>=0;i--){
    
    
            if (chars[i]==c){
    
    
                for (int k=replaceStr.length()-1;k>=0;k--){
    
    
                    newChars[j] = replaceStr.charAt(k);
                    j--;
                }
            }else {
    
    
                newChars[j] = chars[i];
                j--;
            }
        }
        return String.valueOf(newChars);
    }
}

leetcode151.翻转字符串里的单词

这个题用spilt是偷懒的……

class Solution {
    
    
    public String reverseWords(String s) {
    
    
        String[] stmp = s.split("\\s+");
        String result = "";
        for (int i=stmp.length-1;i>=0;i--){
    
    
            if (i==0) result+=stmp[i];
            else {
    
    
                result = result + stmp[i] +" ";
            }
        }

        return result.trim();
    }
}

这个是偷懒版的,如果追求不偷懒呢:
思路如下
1.首先去除空格
2.翻转整个字符串
3.再根据空格识别单词并翻转即可

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

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 1:
输入: s = “abcdefg”, k = 2
输出: “cdefgab”

示例 2:
输入: s = “lrloseumgh”, k = 6
输出: “umghlrlose”
限制:
1 <= k < s.length <= 10000

**思路:**这题图简单就是一行substring的事,但是对题侮辱性很强……

class Solution {
    
    
    public String reverseLeftWords(String s, int n) {
    
    
        return s.substring(n)+s.substring(0,n);
    }
}

如果不调用库函数呢?而且要求空间尽可能省
思路:
反转区间为前n的子串
反转区间为n到末尾的子串
反转整个字符串
不过我这个反而不如调库函数的快和空间省,我吐了,是我StringBuilder搞太多了

 public String reverseLeftWords(String s, int n) {
    
    
        String str1 = new StringBuilder(s.substring(0,n)).reverse().toString();
        String str2 = new StringBuilder(s.substring(n)).reverse().toString();
        return new StringBuilder(str1+str2).reverse().toString();
    }

leetcode28. 实现 strStr()

相当重要之KMP
kmp首先要生成模式串(小串,要在大串中被找到的那个)的next数组,然后通过这个next数组,再去遍历大串。
KMP好处:就是大串不需要回退,直接根据模式串next数组去判断,该模式串的哪位继续比较。

class Solution {
    
    
	//生成next数组
    public int[] getnext(String s){
    
    
    	//next数组初始化
        int n = s.length();
        int[] next = new int[n];
        //j是一个
        int j=0;
        for (int i=1;i<n;i++){
    
    
        	//如果j一直找不到前缀与后面的字符相同的,那就一直回退,
        	//前缀s.substring(0,j+1),后缀就是s.substring(i-j)
        	//实际上j一直回退,就是不断地缩小这个前缀串
            while (j>0 && s.charAt(j)!=s.charAt(i)){
    
    
                j = next[j-1];
            }
           	//如果找到了j++,如果j=0,且该字符与最初的字符也不相等那j=0
            if (s.charAt(j)==s.charAt(i)){
    
    
                j++;
            }
            //给next赋值j
            next[i] = j;

        }
        return next;
    }

    public int strStr(String haystack, String needle) {
    
    
        if(needle==null||"".equals(needle)) return 0;
        else{
    
    
        //初始化j,n,生成next数组
        int[] next = getnext(needle);
        int n = haystack.length();
        int j=0;
        for (int i=0;i<n;i++){
    
    
        	//字符不匹配,需要回退,根据next数组查找模式串需要回退到哪一位
            while (j>0&&needle.charAt(j)!=haystack.charAt(i)){
    
    
                j = next[j-1];
            }
            //如果最后一次匹配上了 j++
            if (needle.charAt(j)==haystack.charAt(i)){
    
    
                j++;
            }
            //如果模式串匹配完成,返回inde
            if (j==needle.length()){
    
    
                return i-needle.length()+1;
            }

        }
        return -1;
        }
    }
}

leetcode题目459.重复的子字符串

给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

示例 1:
输入: “abab”
输出: True
解释: 可由子字符串 “ab” 重复两次构成。

示例 2:
输入: “aba”
输出: False

示例 3:
输入: “abcabcabcabc”
输出: True
解释: 可由子字符串 “abc” 重复四次构成。(或者子字符串 “abcabc” 重复两次构成。)
思路:该题是根据next数组的特性做的
如果next数组的最后一位不为0,且,(字符串长度-最后一位)这个值能被字符串长度整除,那么这个字符串就是由几个重复的子字符串构成的

class Solution {
    
    
    public static int[] getnext(String s){
    
    
        int n = s.length();
        int[] next = new int[n];
        int j=0;
        for (int i=1;i<n;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;

        }
        return next;
    }
    public boolean repeatedSubstringPattern(String s) {
    
    
        int[] next = getnext(s);
        if (next[s.length()-1]!=0&&s.length()%(s.length()-next[s.length()-1])==0){
    
    
            return true;
        }
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_38857307/article/details/114000425