Leetcode算法题-字符串

KMP算法

public int[] getNext(String modelString) {
        int[] next = new int[modelString.length() + 1];
        next[0] = -1;
        int i = 0, j = -1;
        while (i < modelString.length()) {
            if (j == -1 || modelString.charAt(i) == modelString.charAt(j)) {
                i++;
                j++;
                next[i] = j;
            } else j = next[j];
        }
        return next;
    }

    public int KMP(String mainString, String modelString, int[] next) {
        int i = 0, j = 0;
        while (i < mainString.length() && j < modelString.length()) {
            if (j == -1 || mainString.charAt(i) == modelString.charAt(j)) {
                i++;
                j++;
            } else j = next[j];
        }
        if (j == modelString.length()) return i - j;
        else return -1;
}

3. 无重复字符的最长子串

力扣

思路:采用滑动窗口
public int lengthOfLongestSubstring(String s) {
        HashMap<Character,Integer> map = new HashMap<>();
        int max = 0, left = 0;
        for (int i = 0; i < s.length(); i++) {
            if (map.containsKey(s.charAt(i))) {
                left = Math.max(left, map.get(s.charAt(i)) + 1);
            }
            map.put(s.charAt(i), i);
            max = Math.max(max, i - left + 1);
        }
        return max;
}

5. 最长回文子串

力扣

public String longestPalindrome(String s) {
        if (s == null || s.length() < 2) return s;
        boolean[][] dp = new boolean[s.length()][s.length()];
        int maxlen = 1, start = 0;
        for (int i = 0; i < s.length(); i++) {
            dp[i][i] = true;
            for (int j = 0; j < i; j++) {
                if (s.charAt(i) == s.charAt(j) && (j + 1 == i || dp[j + 1][i - 1])) {
                    dp[j][i] = true;
                    if (i - j + 1 > maxlen) {
                        start = j;
                        maxlen = i - j + 1;
                    }
                }
            }
        }
        return s.substring(start,start + maxlen);
    }

6. Z 字形变换

class Solution {
    public String convert(String s, int numRows) {
        if (numRows == 1) return s;
        List<StringBuilder> rows = new ArrayList<>();
        for (int i = 0; i < numRows; i++) {
            rows.add(new StringBuilder());
        }
        int curRow = 0;
        boolean goDown = false;
        for (char c : s.toCharArray()) {
            rows.get(curRow).append(c);
            if (curRow == 0 || curRow == numRows - 1) {
                goDown = !goDown;
            }
            curRow += goDown ? 1 : -1;
        }
        StringBuilder sb = new StringBuilder();
        for (StringBuilder row : rows) {
            sb.append(row);
        }
        return sb.toString();
    }
}

20. 有效的括号

力扣

public boolean isValid(String s) {
        HashMap<Character,Character> map = new HashMap<>();
        map.put('(',')');map.put('{','}');map.put('[',']');
        Deque<Character> stack = new ArrayDeque<>();
        for (Character c : s.toCharArray()) {
            if (!stack.isEmpty() && map.get(stack.peek()) == c) stack.pop();
            else stack.push(c);
        }
        return stack.isEmpty();
    }

43. 字符串相乘

力扣

public String multiply(String num1, String num2) {
        if (num1.equals("0") || num2.equals("0")) return "0";
        int[] res = new int[num1.length() + num2.length()];
        for (int i = num1.length() - 1; i >= 0; i--) {
            int n1 = num1.charAt(i) - '0';
            for (int j = num2.length() - 1; j >= 0; j--) {
                int n2 = num2.charAt(j) - '0';
                int sum = res[i + j + 1] + n1 * n2;
                res[i + j + 1] = sum % 10;
                res[i + j] += sum / 10;
            }
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < res.length; i++) {
            if (i == 0 && res[i] == 0) continue;
            sb.append(res[i]);
        }
        return sb.toString();
}

159. 至多包含两个不同字符的最长子串

力扣

class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        int n = s.length();
        if (n < 3) return n;
        int left = 0, right = 0;
        HashMap<Character, Integer> hashMap = new HashMap<>();
        int max_len = 2;
        while (right < n) {
            if (hashMap.size() < 3) {
                hashMap.put(s.charAt(right), right++);
            }
            if (hashMap.size() == 3) {
                int del_idx = Collections.min(hashMap.values());
                hashMap.remove(s.charAt(del_idx));
                left = del_idx + 1;
            }
            max_len = Math.max(max_len, right - left);
        }
        return max_len;
    }
}

161. 相隔为 1 的编辑距离

力扣

class Solution {
    public boolean isOneEditDistance(String s, String t) {
        int ns = s.length(),nt = t.length();
        if (ns > nt) return isOneEditDistance(t,s);
        if (nt - ns > 1) return false;
        for (int i = 0; i < ns; i++) {
            if (s.charAt(i) != t.charAt(i)) {
                if (ns == nt) return s.substring(i + 1).equals(t.substring(i + 1));
                else return s.substring(i).equals(t.substring(i + 1));
            }
        }
        return (ns + 1 == nt);
    }
}

 214. 最短回文串

力扣

public String shortestPalindrome(String s) {
        String reverse = new StringBuilder(s).reverse().toString();
        String pattern = s + "#" + reverse;
        int index = getNext(pattern)[pattern.length()];
        return reverse.substring(0,reverse.length() - index) + s;
    }

    public int[] getNext(String pattern) {
        int n = pattern.length();
        int[] next = new int[n + 1];
        next[0] = -1;
        int i = 0, j = -1;
        while (i < n) {
            if (j == -1 || pattern.charAt(i) == pattern.charAt(j)) {
                i++;
                j++;
                next[i] = j;
            } else j = next[j];
        }
        return next;
    }

409. 最长回文串

力扣

public int longestPalindrome(String s) {
        int[] alphabet = new int[59];
        int res = 0, odd = 0;
        for (Character c : s.toCharArray()) {
            alphabet[c - 'A']++;
        }
        for (int i = 0; i < 59; i++) {
            if (alphabet[i] % 2 == 0) res += alphabet[i];
            else {
                res += alphabet[i] - 1;
                odd = 1;
            }
        }
        return res + odd;
    }

415. 字符串相加

力扣

public String addStrings(String num1, String num2) {
        int i = num1.length() - 1, j = num2.length() - 1, add = 0;
        StringBuilder sb = new StringBuilder();
        while (i >= 0 || j >= 0 || add != 0) {
            int x = i >= 0 ? num1.charAt(i) - '0' : 0;
            int y = j >= 0 ? num2.charAt(j) - '0' : 0;
            int result = x + y + add;
            sb.append(result % 10);
            add = result / 10;
            i--;j--;
        }
        return sb.reverse().toString();
    }

434. 字符串中的单词数

力扣

class Solution {
    public int countSegments(String s) {
        int res = 0;
        for (int i = 0; i < s.length(); i++) {
            if ((i == 0 || s.charAt(i - 1) == ' ') && s.charAt(i) != ' ') {
                res++;
            }
        }
        return res;
    }
}

647. 回文串

力扣

我自己做的是枚举所有的子串
class Solution {
    public int countSubstrings(String s) {
        int n = s.length(), ans = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 1; i + j <= n; j++) {
                String sub = s.substring(i,i + j);
                if (isPalString(sub)) ans++;
            }
        }
        return ans;
    }

    public boolean isPalString(String s) {
        int i = 0, j = s.length() - 1;
        while (i < j) {
            if (s.charAt(i) == s.charAt(j)) {
                i++;j--;
            } else return false;
        }
        return true;
    }
}
枚举回文串中心
public int countSubstrings(String s) {
        int n = s.length(), ans = 0;
        for (int i = 0; i < 2 * n - 1; ++i) {
            int l = i / 2, r = i / 2 + i % 2;
            while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) {
                --l;
                ++r;
                ++ans;
            }
        }
        return ans;
    }

680. 验证回文串 II

力扣

public boolean palindrome(String s, int i, int j) {
        for (; i < j && s.charAt(i) == s.charAt(j); i++, j--);
        return i >= j;
    }
    public boolean validPalindrome(String s) {
        int i = 0, j = s.length() - 1;
        for (; i < j && s.charAt(i) == s.charAt(j);i++,j--);
        return palindrome(s, i, j - 1) || palindrome(s, i + 1, j);
    }

844. 比较含退格的字符串

力扣

public boolean backspaceCompare(String S, String T) {
        return build(S).equals(build(T));
    }
    
    public String build(String str) {
        StringBuilder sb = new StringBuilder();
        int length = str.length();
        for (int i = 0; i < length; i++) {
            char ch = str.charAt(i);
            if (ch != '#') sb.append(ch);
            else {
                if (sb.length() > 0) sb.deleteCharAt(sb.length() - 1);
            }
        }
        return sb.toString();
    }

1071. 字符串的最大公因子

力扣

思路很简单: 如果str1 + str2 == str2 + str1则说明TTT + TTTTT == TTTTT TTT有公共因子
那么公共因子的位数就可以通过gcd(str1.length,str2.length)求得,返回str1.substring(0,gcd)就行
class Solution {
    public String gcdOfStrings(String str1, String str2) {
        if (!(str1 + str2).equals(str2 + str1)) return "";
        return str1.substring(0,gcd(str1.length(), str2.length()));
    }
    private static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
}

面试题 01.01. 判定字符是否唯一

力扣

public boolean isUnique(String astr) {
        boolean[] map = new boolean[128];
        for (char c : astr.toCharArray()) {
            if (map[c] == false) map[c] = true;
            else return false;
        }
        return true;
    }

面试题 01.02. 判定是否互为字符重排

力扣

public boolean CheckPermutation(String s1, String s2) {
        if (s1.length() != s2.length()) return false;
        int[] map = new int[128];
        for (int i = 0; i < s1.length(); i++) {
            map[s1.charAt(i)]++;
            map[s2.charAt(i)]--;
        }
        for (int i = 0; i < 128; i++) {
            if (map[i] != 0) return false;
        }
        return true;
    }

面试题 01.03. URL化

力扣

public String replaceSpaces(String S, int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            if (S.charAt(i) == ' ') sb.append("%20");
            else sb.append(S.charAt(i));
        }
        return sb.toString();
    }

面试题 01.04. 回文排列

力扣

public boolean canPermutePalindrome(String s) {
        int[] map = new int[128];
        boolean odd = false;
        for (char c : s.toCharArray()) {
            map[c]++;
        }
        for (int i = 0; i < 128; i++) {
            if (map[i] % 2 == 1) {
                if (odd) return false;
                else odd = true;
            }
        }
        return true;
    }

面试题 01.05. 一次编辑

力扣

public boolean oneEditAway(String first, String second) {
        if (first == null || second == null) return false;
        int len1 = first.length();
        int len2 = second.length();
        if (Math.abs(len1 - len2) > 1) return false;
        if (len1 < len2) return oneEditAway(second, first);
        for (int i = 0; i < len2; i++) {
            if (first.charAt(i) != second.charAt(i)) {
                return first.substring(i + 1).equals(second.substring(len1 == len2 ? i + 1 : i));
            }
        }
        return true;
    }

面试题 01.06. 字符串压缩

力扣

public String compressString(String S) {
        if (S == null || S.length() < 2) return S;
        char target = S.charAt(0);
        int count = 1;
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i < S.length(); i++) {
            if (S.charAt(i) == target) {
                count++; 
            } else {
                sb.append(target).append(count);
                target = S.charAt(i);
                count = 1;
            }
            if (i == S.length() - 1) sb.append(target).append(count);
        }
        if (sb.length() < S.length()) return sb.toString();
        else return S;
    }

面试题 01.07. 旋转矩阵

力扣

public void rotate(int[][] matrix) {
        int N = matrix.length;
        for (int i = 0; i < N / 2; i++) {
            for (int j = 0; j < (N + 1) / 2; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[N - 1 - j][i];
                matrix[N - 1 - j][i] = matrix[N - 1 - i][N - 1 - j];
                matrix[N - 1 - i][N - 1 - j] = matrix[j][N - 1 - i];
                matrix[j][N - 1 - i] = temp;
            }
        }
    }

面试题 01.08. 零矩阵

力扣

public void setZeroes(int[][] matrix) {
        boolean colhaszero = false;
        boolean rowhaszero = false;
        for (int i = 0; i < matrix.length; i++) {
            if (matrix[i][0] == 0) {
                rowhaszero = true;break;
            }
        }
        for (int i = 0; i < matrix[0].length; i++) {
            if (matrix[0][i] == 0) {
                colhaszero = true;break;
            }
        }

        for (int i = 1; i < matrix.length; i++) {
            for (int j = 1; j < matrix[0].length; j++) {
                if (matrix[i][j] == 0) {
                    matrix[0][j] = 0;
                    matrix[i][0] = 0;
                }
            }
        }

        for (int i = 1; i < matrix.length; i++) {
            for (int j = 1; j < matrix[0].length; j++) {
                if (matrix[0][j] == 0 || matrix[i][0] == 0) matrix[i][j] = 0;
            }
        }

        if (rowhaszero) {
            for (int i = 0; i < matrix.length; i++) matrix[i][0] = 0;
        }
        if (colhaszero) {
            for (int i = 0; i < matrix[0].length; i++) matrix[0][i] = 0;
        }
    }

面试题 01.09. 字符串轮转

力扣

public boolean isFlipedString(String s1, String s2) {
        return s1.length() == s2.length() && (s1 + s1).contains(s2);
    }

剑指offer 44. 数字序列中某一位的数字

力扣

digit = 1(位数) ,start = 1, count = 9; 
public int findNthDigit(int n) {
        int digit = 1;
        long start = 1;
        long count = 9;
        while (n > count) {
            n -= count;
            digit += 1;
            start *= 10;
            count = digit * start * 9;
        }
        long num = start + (n - 1) /digit;
        return Long.toString(num).charAt((n - 1) % digit) - '0';
}

剑指offer 58 -I 翻转单词顺序

力扣

public String reverseWords(String s) {
        String[] words = s.trim().split(" ");
        StringBuilder sb = new StringBuilder();
        for (int i = words.length - 1; i >= 0; i--) {
            if (!words[i].trim().equals("")) {
                sb.append(words[i]);
                if (i != 0) sb.append(" ");
            }
        }
        return sb.toString();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值