字符串算法题

1 替换空格-剑指offer

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

方法一

public class Solution {
    public String replaceSpace(StringBuffer str) {
        StringBuffer result = new StringBuffer();
        for(int i = 0;i < str.length();i++){
            if(String.valueOf(str.charAt(i)).equals(" ")){
                result.append("%20");
            }
            else{
                result.append(str.charAt(i));
            }
        } 
        return result.toString();
    }
}

方法二 简单的

public class Solution {
    public String replaceSpace(StringBuffer str) {
        return str.toString().replaceAll(" ","%20");
    }
}

2最长公共前缀-leetcode

Leetcode: 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。

输入: [“flower”,“flow”,“flight”]
输出: “fl”
以第一个字符串为标准,和剩下的字符串一个个进行比较,如不相同则返回之前对比完且相同的字符子串,注意此处对比第一个子串index不能越界大于剩下的子串

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs == null||strs.length == 0)
            return "";

        for(int i = 0;i < strs[0].length();i++){

            char c = strs[0].charAt(i);
            for(int j = 1;j < strs.length;j++){
                if(i >= strs[j].length()||c != strs[j].charAt(i)){
                    return strs[0].substring(0,i);
                }
            }
        }
        return strs[0];
    }
}

3最长回文串

LeetCode: 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串

class Solution {
    public int longestPalindrome(String s) {
        HashSet<Character> hashset = new HashSet<Character>();

        int count = 0;
        for(int i = 0;i < s.length();i++){
            if(!hashset.contains(s.charAt(i))){
                hashset.add(s.charAt(i));
            }
            else{
                hashset.remove(s.charAt(i));
                count++;
            }
        }

        return hashset.isEmpty()?count * 2:count * 2 + 1;
    }
}

4验证回文串

LeetCode: 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 说明:本题中,我们将空字符串定义为有效的回文串,即不考虑空格。

class Solution {
    public boolean isPalindrome(String s) {
        if(s.length() == 0)
            return true;

        int l = 0,r = s.length() -1;

        while(l < r){
            if(!Character.isLetterOrDigit(s.charAt(l))){
                l++;
            }else if(!Character.isLetterOrDigit(s.charAt(r))){
                r--;
            }else{
                if(Character.toLowerCase(s.charAt(l)) == Character.toLowerCase(s.charAt(r))){
                    l++;
                    r--;
                }else{
                    return false;
                }
            }
        }
        return true;
    }
}

5寻找最长回文子串
LeetCode: 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。

class Solution {
    private int index = 0;
    private int len = 0;
    public String longestPalindrome(String s) {

        if(s.length() <= 1)
            return s;

        for(int i = 0;i < s.length() - 1;i++){
            funtion(s,i,i);
            funtion(s,i,i + 1);
        }

        实际返回的是[index] - [index + len - 1]
        return s.substring(index,index + len);
    }


    public void funtion(String s,int l,int r){
        while(l >= 0&&r < s.length()&&s.charAt(l) == s.charAt(r)){
            l--;
            r++;
        }

        //注意此时的l r 位置处于不匹配的位置上
        if(len < r - l + 1 - 2){
            len = r - l + 1 - 2;
            index = l + 1;
        }
    }
}

6最长回文子序列-动态规划 重要

最长回文子序列 给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000。最长回文子序列和上一题最长回文子串的区别是,子串是字符串中连续的一个序列,而子序列是字符串中保持相对位置的字符序列,例如,"bbbb"可以是字符串"bbbab"的子序列但不是子串。

解题思路:

状态 f[i][j] 表示 s 的第 i 个字符到第 j 个字符组成的子串中,最长的回文序列长度是多少。

转移方程 如果 s 的第 i 个字符和第 j 个字符相同的话

f[i][j] = f[i + 1][j - 1] + 2

如果 s 的第 i 个字符和第 j 个字符不同的话

f[i][j] = max(f[i + 1][j], f[i][j - 1])

然后注意遍历顺序,i 从最后一个字符开始往前遍历,j 从 i + 1 开始往后遍历,这样可以保证每个子问题都已经算好了。

初始化 f[i][i] = 1 单个字符的最长回文序列是 1

结果 f[0][n - 1]

class Solution {
    public int longestPalindromeSubseq(String s) {
        int n = s.length();

        int[][] arr = new int[n][n];
        //定义arr[i][j]为索引i到j子字符串中最大的回文子序列
        //则初始化arr[i][i]为1

        for(int i = n - 1;i >= 0;i--){
            arr[i][i] = 1;
            for(int j = i + 1;j < n;j++){

                //转移方程
                if(s.charAt(i) == s.charAt(j)){
                    arr[i][j] = arr[i + 1][j - 1] + 2;
                }else{
                    arr[i][j] = Math.max(arr[i + 1][j],arr[i][j - 1]);
                }
            }
        }
        return arr[0][n -1];
    }
}

7把字符串转换成整数

剑指offer: 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。

public class Solution {
    public int StrToInt(String str) {
        if(str.length() == 0){
            return 0;
        }
        char[] arr = str.toCharArray();

        //默认为正
        int flag = 1;
        int start = 0;
        //判断符号
        if(arr[0] == '-'){
            start = 1;
            flag = -1;
        }
        else if(arr[0] =='+'){
            start = 1;
        }

        int res = 0;
        for(int i = start;i < arr.length;i++){
            int temp;
            if(Character.isDigit(arr[i])){
                temp = arr[i] - '0';
            }else{
                return 0;
            }

            res = res * 10 + temp;
        }

        return flag == 1?res:-res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值