leetcode精选TOP面试题_字符串

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

什么是滑动窗口?

其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?

我们只要把队列的左边的元素移出就行了,直到满足题目要求!一直维持这样的队列,找出队列出现最长的长度时候,求出解!

时间复杂度:O(n)。

Java解决方法:

需要一种数据结构来判断是否有重复字符:HashSet。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Set<Character> ss = new HashSet<Character>();
        int slen = s.length();
        int length = 0;
        int maxLength = 0;
        for(int i = 0; i < slen; i++)
        {
            //退出队列中的一个元素
            if(i != 0)
            {
                ss.remove(s.charAt(i - 1));
            }
            //向队列中加入元素,加入时HashSet会自动判断有无重复
            while(length < slen  && ss.add(s.charAt(length)))
            {
                length++;
            }
            if(maxLength < length - i)
            {
                maxLength = length - i;
            }
        }
        return maxLength;
    }
}

C语言解决方法:

bool haveSame(char *ss, int start, int end, char c)
{
    int i = start;
    if(end == 0)
    {
        return true;
    }
    while(i < end && ss[i] != c)
    {
        i++;
    }
    if(i >= end)
    {
        return true;
    }
    else
    {
        return false;
    }
}
int lengthOfLongestSubstring(char * s){
    char *ss = NULL;
    int len;
    len = strlen(s);
    ss = (char *)malloc(len * sizeof(char));
    int length = 0;
    int maxLength = 0;
    for(int i = 0; i < len; i++)
    {
        //向队列中加入元素,加入时HashSet会自动判断有无重复
        while(length < len  && haveSame(ss, i, length, s[length]))
        {
            ss[length] = s[length];
            length++;
        }
        if(maxLength < length - i)
        {
            maxLength = length - i;
        }
    }
    return maxLength;
}

5. 最长回文子串

该题需要使用动态规划方法来求解。

判断一个串是不是回文串,有以下函数:

 动态规划的状态转移方程:

P(i, j)=P(i+1, j-1) \wedge\left(S_{i}==S_{j}\right)

动态规划的边界条件:

\left\{\begin{array}{l} P(i, i)=\text { true } \\ P(i, i+1)=\left(S_{i}==S_{i+1}\right) \end{array}\right.

注意:在状态转移方程中,我们是从长度较短的字符串向长度较长的字符串进行转移的,因此一定要注意动态规划的循环顺序。

Java解决方法:

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        if(len < 2)
        {
            return s;
        }
        int maxlen = 1;
        int begin = 0;
        boolean[][] bp = new boolean[len][len];
        for(int i = 0; i < len; i++)
        {
            bp[i][i] = true;
        }
        //先枚举子串的长度
        for(int L = 2; L <= len; L++)
        {
            //枚举左边界
            for(int i1 = 0; i1 < len; i1++)
            {
                //枚举右边界
                int i2 = i1 + L - 1;
                if(i2 >= len)
                {
                    break;
                }
                //比较两端的元素,01,12,23,02,13,03
                if(s.charAt(i1) != s.charAt(i2))
                {
                    bp[i1][i2] = false;
                }
                else
                {
                    if(i2 - i1 < 3)
                    {
                        bp[i1][i2] = true;
                    }
                    else
                    {
                        //bp[i1 + 1][i2 - 1]前面计算过,因为i2-1<i2.
                        bp[i1][i2] = bp[i1 + 1][i2 - 1];
                    }
                }
                if(bp[i1][i2] && i2 - i1 + 1 > maxlen)
                {
                    maxlen = i2 - i1 + 1;
                    begin = i1;
                }
            }
        }
        return s.substring(begin, begin + maxlen);
    }
}

C解决方法:

vs上面能运行成功,但是leetcode上面报错了。

char * longestPalindrome(char * s){
    int len, begin, maxlen, i, j, L, i1, i2, i3;
    bool *bp;
    char *str;
    len = strlen(s);
    if(len < 2)
    {
        return s;
    }
    begin = 0;
    maxlen = 1;
    bp = (bool *)malloc(len * len * sizeof(bool));
    //bp[i][i] = true
    for(i = 0; i < len; i++)
    {
        j = i;
        bp[i * len + j] = true;
    }
    for(L = 2; L <= len; L++)
    {
        //确定左端元素
        for(i1 = 0; i1 < len; i1++)
        {
            //确定右端元素
            i2 = i1 + L - 1;
            if(i2 >= len)
            {
                break;
            }
            if(s[i1] != s[i2])
            {
                bp[i1 * len + i2] = false;
            }
            else
            {
                if(i2 - i1 < 3)
                {
                    bp[i1 * len + i2] = true;
                }
                else
                {
                    bp[i1 * len + i2] = bp[(i1 + 1) * len + (i2 - 1)];
                }
            }
            if(bp[i1 * len + i2] && i2 - i1 + 1 > maxlen)
            {
                maxlen = i2 - i1 + 1;
                begin = i1;
            }
        }
    }
    str = (char *)malloc(maxlen * sizeof(char));
    for(i3 = 0; i3 < maxlen; i3++)
    {
        str[i3] = s[begin++];
    }
    str[i3] = '\0';
    return str;
}

接下来这个可以在leetcode上面运行成功。 

char * longestPalindrome(char * s){
    int n = strlen(s);
    if (n < 2) {
        return s;
    }

    int maxLen = 1;
    int begin = 0;
    // dp[i][j] 表示 s[i..j] 是否是回文串
    int dp[n][n];
    // 初始化:所有长度为 1 的子串都是回文串
    for (int i = 0; i < n; i++) {
        dp[i][i] = true;
    }

    // 递推开始
    // 先枚举子串长度
    for (int L = 2; L <= n; L++) {
        // 枚举左边界,左边界的上限设置可以宽松一些
        for (int i = 0; i < n; i++) {
            // 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
            int j = L + i - 1;
            // 如果右边界越界,就可以退出当前循环
            if (j >= n) {
                break;
            }

            if (s[i]!= s[j]) {
                dp[i][j] = false;
            } else {
                if (j - i < 3) {
                    dp[i][j] = true;
                } else {
                    dp[i][j] = dp[i + 1][j - 1];
                }
            }

            // 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
            if (dp[i][j] && j - i + 1 > maxLen) {
                maxLen = j - i + 1;
                begin = i;
            }
        }
    }
    s[begin+maxLen]='\0';
    s=&s[begin];
    return s;
}

8. 字符串转整数(atoi)

 

 Java解决方法:

class Solution {
    public int myAtoi(String s) {
        int len;
        int flag = 1;
        int start = 0;
        long sum = 0;
        int count = 0;
        len = s.length();
        //消除空格
        if(len == 0)
        {
            return 0;
        }
        while(start < len && s.charAt(start) == ' ')
        {
            start++;
        }
        //判断+-
        if(start == len)
        {
            return 0;
        }
        if(s.charAt(start) == '-')
        {
            flag = -1;
            start++;
        }
        else if(s.charAt(start) == '+')
        {
            start++;
        }
        //读入数字
        if(start == len)
        {
            return 0;
        }
        while(start < len && s.charAt(start) == '0')
        {
            start++;
        }
        if(start == len)
        {
            return 0;
        }
        while(start < len && Character.isDigit(s.charAt(start)))
        {
            //超出int的范围就截断
            if(count < 11)
            {
                 sum = sum * 10 + Character.digit(s.charAt(start), 10);
                 start++;
                 count++;
            }
            else
            {
                break;
            }
        }
        sum = flag * sum;
        if(sum > 2147483647)
        {
            return 2147483647;
        }
        else if(sum < -2147483648)
        {
            return -2147483648;
        }
        else
        {
            return (int)sum;
        }


    }
}

 C解决方法:

int myAtoi(char * s){
    int len;
    int flag = 1;
    int start = 0;
    long sum = 0;
    int count = 0;
    len = strlen(s);
    //消除空格
    if(len == 0)
    {
        return 0;
    }
    while(start < len && s[start] == ' ')
    {
        start++;
    }
    //判断+-
    if(start == len)
    {
        return 0;
    }
    if(s[start] == '-')
    {
        flag = -1;
        start++;
    }
    else if(s[start] == '+')
    {
        start++;
    }
    //读入数字
    if(start == len)
    {
        return 0;
    }
    while(start < len && s[start] == '0')
    {
        start++;
    }
    if(start == len)
    {
        return 0;
    }
    while(start < len && isdigit(s[start]))
    {
        //超出int的范围就截断
        if(count < 11)
        {
            sum = sum * 10 + s[start] - '0';
            start++;
            count++;
        }
        else
        {
            break;
        }
    }
    sum = flag * sum;
    if(sum > 2147483647)
    {
        return 2147483647;
    }
    else if(sum < -2147483648)
    {
        return -2147483648;
    }
    else
    {
        return (int)sum;
    }
}

13. 罗马数字转整数 

 

 Java解决方法

class Solution {
    public int romanToInt(String s) {
        int len = s.length();
        int start = 0;
        int sum = 0;
        while(start < len)
        {
            char c = s.charAt(start);
            switch(c)
            {
                case 'M':
                {
                    sum = sum + 1000;
                    start++;
                    break;
                }
                case 'D':
                {
                    sum = sum + 500;
                    start++;
                    break;
                }
                case 'C':
                {
                   if((start + 1 < len) && s.charAt(start + 1) == 'D')
                    {
                        sum = sum + 400;
                        start = start + 2;
                    }
                    else if((start + 1 < len) && s.charAt(start + 1) == 'M')
                    {
                        sum = sum + 900;
                        start = start + 2;
                    }
                    else
                    {
                        sum = sum + 100;
                        start++;
                    }
                    break;
                }
                case 'L':
                {
                    sum = sum + 50;
                    start++;
                    break;
                }
                case 'X':
                {
                    if((start + 1 < len) && s.charAt(start + 1) == 'L')
                    {
                        sum = sum + 40;
                        start = start + 2;
                    }
                    else if((start + 1 < len) && s.charAt(start + 1) == 'C')
                    {
                        sum = sum + 90;
                        start = start + 2;
                    }
                    else
                    {
                        sum = sum + 10;
                        start++;
                    }
                    break;
                }
                case 'V':
                {
                    sum = sum + 5;
                    start++;
                    break;
                }
                case 'I':
                {
                    if((start + 1 < len) && s.charAt(start + 1) == 'V')
                    {
                        sum = sum + 4;
                        start = start + 2;
                    }
                    else if((start + 1 < len) && s.charAt(start + 1) == 'X')
                    {
                        sum = sum + 9;
                        start = start + 2;
                    }
                    else
                    {
                        sum = sum + 1;
                        start++;
                    }
                    break;
                }
            }
        }
        return sum;
    }
}

C语言解决方法:

int romanToInt(char * s){
    int len = strlen(s);
    int start = 0;
    int sum = 0;
    while(start < len)
    {
        switch(s[start])
        {
            case 'M':
            {
                sum = sum + 1000;
                start++;
                break;
            }
            case 'D':
            {
                sum = sum + 500;
                start++;
                break;
            }
            case 'C':
            {
                if((start + 1 < len) && s[start + 1] == 'D')
                {
                    sum = sum + 400;
                    start = start + 2;
                }
                else if((start + 1 < len) && s[start + 1] == 'M')
                {
                    sum = sum + 900;
                    start = start + 2;
                }
                else
                {
                    sum = sum + 100;
                    start++;
                }
                break;
            }
            case 'L':
            {
                sum = sum + 50;
                start++;
                break;
            }
            case 'X':
            {
                if((start + 1 < len) && s[start + 1] == 'L')
                {
                    sum = sum + 40;
                    start = start + 2;
                }
                else if((start + 1 < len) && s[start + 1] == 'C')
                {
                    sum = sum + 90;
                    start = start + 2;
                }
                else
                {
                    sum = sum + 10;
                    start++;
                }
                break;
            }
            case 'V':
            {
                sum = sum + 5;
                start++;
                break;
            }
            case 'I':
            {
                if((start + 1 < len) && s[start + 1] == 'V')
                {
                    sum = sum + 4;
                    start = start + 2;
                }
                else if((start + 1 < len) && s[start + 1] == 'X')
                {
                    sum = sum + 9;
                    start = start + 2;
                }
                else
                {
                    sum = sum + 1;
                    start++;
                }
                break;
            }
        }
    }
    return sum;
}

14. 最长公共前缀

 Java解决方法:

class Solution {
    public String longestCommonPrefix(String[] strs) {
        String str = "";
        int num = strs.length;
        if(num == 0)
        {
            return str;
        }
        for(int i = 0; i < strs[0].length(); i++)
        {
            char c = strs[0].charAt(i);
            int i1 = 1;
            while(i1 < num)
            {
                if(i < strs[i1].length() && strs[i1].charAt(i) == c)
                {
                    i1++;
                }
                else
                {
                    return str;
                }
            }
            str = str + c;
        }
        return str;
    }
}

C解决方法:

char * longestCommonPrefix(char ** strs, int strsSize){
    int i = 0;
    int i1;
    if(strsSize == 0)
    {
        return "";
    }
    for(; i < strlen(strs[0]); i++)
    {
        char c = strs[0][i];
        i1 = 1;
        while(i1 < strsSize)
        {
            if(i < strlen(strs[i1]) && strs[i1][i] == c)
            {
                i1++;
            }
            else
            {
                strs[0][i] = '\0';
                return strs[0];
            }
        }
    }
    strs[0][i] = '\0';
    return strs[0]; 
}

17. 电话号码的自由组合

 java解决方法:

class Solution {
    public List<String> letterCombinations(String digits) {
        //list,map只是一个接口,不能创建实例,采用多态,就可以创建对象,只能用继承后的方法(包括修改后的)
        List<String> conbinations = new ArrayList<String>();
        if(digits.length() == 0)
        {
            return conbinations;
        }
        //
        Map<Character, String> phoneMap = new HashMap<Character, String>();
        phoneMap.put('2', "abc");
        phoneMap.put('3', "def");
        phoneMap.put('4', "ghi");
        phoneMap.put('5', "jkl");
        phoneMap.put('6', "mno");
        phoneMap.put('7', "pqrs");
        phoneMap.put('8', "tuv");
        phoneMap.put('9', "wxyz");
        //采用回溯法来求组合后的全部结果, StringBuffer()是组合的一个结果
        backtrack(conbinations, phoneMap, digits, 0, new StringBuffer());
        return conbinations;
    }
    void backtrack(List<String> conbinations, Map<Character, String> phoneMap, String digits, int index, StringBuffer conbination)
    {
        if(index == digits.length())
        {
            conbinations.add(conbination.toString());
        }
        else
        {
            char digit = digits.charAt(index);
            //获得数字字符对应的字符串
            String letters = phoneMap.get(digit);
            int len_letters = letters.length();
            for(int i = 0; i < len_letters; i++)
            {
                //将字符串中的一个字符加入其中
                conbination.append(letters.charAt(i));
                //将下一个数字对应的一个字符加入其中
                backtrack(conbinations, phoneMap, digits, index + 1, conbination);
                //回溯,将加入字符串中的一个字符删除,将字符串中的另一个字符加入其中
                conbination.deleteCharAt(index);
            }
        }
    }
}

20. 有效的括号

 java解决方法:

class Solution {
    public boolean iscompel(char c1, char c2)
    {
        if((c1 == '(' && c2 == ')') || (c1 == '[' && c2 == ']') || (c1 == '{' && c2 == '}'))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public boolean isValid(String s) {
        Stack s1 = new Stack();
        int start = 0;
        int len = s.length();
        while(start < len)
        {
            char c = s.charAt(start);
            if(s1.empty())
            {
                s1.push(c);
            }
            else
            {
                if(iscompel((char)s1.peek(), c))
                {
                    s1.pop();
                }
                else
                {
                    s1.push(c);
                }
            }
            start++;
        }
        if(s1.empty())
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

C语言解决方法:

bool iscompel(char c1, char c2)
{
    if((c1 == '(' && c2 == ')') || (c1 == '[' && c2 == ']') || (c1 == '{' && c2 == '}'))
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool isValid(char * s){
    char *stack = NULL;
    int len, top, start;
    len = strlen(s);
    top = -1;
    start = 0;
    stack = (char *)malloc(len * sizeof(char *));
    while(start < len)
    {
        if(top == -1)
        {
            top++;
            stack[top] = s[start];
        }
        else
        {
            if(iscompel(stack[top], s[start]))
            {
                top--;
            }
            else
            {
                top++;
                stack[top] = s[start];
            }
        }
        start++;
    }
    if(top == -1)
    {
        return true;
    }
    else
    {
        return false;
    }
}

22. 括号生成

java解决方法:

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> s = new ArrayList<String>();
        backtrack(s, new StringBuilder(), 0, 0, n);
        return s;
    }
    public void backtrack(List<String> s, StringBuilder cur, int open, int close, int max) 
    {
        if(cur.length() == 2 * max)
        {
            s.add(cur.toString());
        }
        else
        {
            //如果左括号数量不大于max,我们可以放一个左括号.
            //如果右括号数量小于左括号的数量,我们可以放一个右括号.可以保证配对的情况
            if(open < max)
            {
                cur.append("(");
                backtrack(s, cur, open + 1, close, max);
                //回溯法
                cur.deleteCharAt(cur.length() - 1);
            }
            if(close < open)
            {
                cur.append(")");
                backtrack(s, cur, open, close + 1, max);
                cur.deleteCharAt(cur.length() - 1);
            }
        }
    }
}

 C解决方法:

// 回溯法求解
void generate(int left, int right, int n, char *str, int index, char **result, int *returnSize) {
    if (index == 2 * n) { // 当前长度已达2n
        result[(*returnSize)] =  (char*)calloc((2 * n + 1), sizeof(char));
        strcpy(result[(*returnSize)++], str);
        return;
    }
    // 如果左括号数量不大于 n,可以放一个左括号
    if (left < n) {
        str[index] = '(';
        generate(left + 1, right, n, str, index + 1, result, returnSize);
    }
    // 如果右括号数量小于左括号的数量,可以放一个右括号
    if (right < left) {
        str[index] = ')';
        generate(left, right + 1, n, str, index + 1, result, returnSize);
    }
}
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
char** generateParenthesis(int n, int *returnSize) {
    int Maxlen[] = {0, 1, 2, 5, 14, 42, 132, 429, 1430}; // n<=8 卡特兰数
    char *str = (char*)calloc((2 * n + 1), sizeof(char));
    char **result = (char **)malloc(sizeof(char *) * Maxlen[n]);
    *returnSize = 0;
    generate(0, 0, n, str, 0, result, returnSize);
    return result;
}

28. 实现strStr()

java解决方法 :

class Solution {
    public int strStr(String haystack, String needle) {
        int i1 = 0;
        int i2 = 0;
        int len1 = haystack.length();
        int len2 = needle.length();
        while(i1 < len1 - len2 + 1)
        {
            int i3 = i1;
            while(i1 < len1 && i2 < len2)
            {
                if(haystack.charAt(i1) == needle.charAt(i2))
                {
                    i1++;
                    i2++;
                }
                else
                {
                    break;
                }
            }
            if(i2 == len2)
            {
                return i1 -i2;
            }
            else
            {
                i1 = i3 + 1;
                i2 = 0;
            }
        }
        return -1;    
    }
}

C语言解决方法:

int strStr(char * haystack, char * needle){
    int i1 = 0;
    int i2 = 0;
    int i3 = 0;
    int len1 = strlen(haystack);
    int len2 = strlen(needle);
    while(i1 < len1 - len2 + 1)
    {
        i3 = i1;
        while(i1 < len1 && i2 < len2)
        {
            if(haystack[i1] == needle[i2])
            {
                i1++;
                i2++;
            }
            else
            {
                break;
            }
        }
        if(i2 == len2)
        {
            return i1 -i2;
        }
        else
        {
            i1 = i3 + 1;
            i2 = 0;
        }
    }
    return -1;
}

38. 外观数列

 Java解决方法:

class Solution {
    public String countAndSay(int n) {
        String str = "1";
        for(int i = 1; i < n; i++)
        {
            int start = 0;
            int end = 0;
            StringBuffer s = new StringBuffer();
            while(end < str.length())
            {
                while(end < str.length() && str.charAt(end) == str.charAt(start))
                {
                    end++;
                }
                s.append(Integer.toString(end - start));
                s.append(str.charAt(start));
                start = end;
            }
            str = s.toString();
        }
        return str;
    }
}

C解决方法:

char * countAndSay(int n){
    int i, start, end, len, ss;
    char *str = (char *)calloc(5000, sizeof(char));
    str[0] = '1';
    for(i = 1; i < n; i++)
    {
        start = 0;
        end = 0;
        char *s = (char *)calloc(5000, sizeof(char));
        ss = 0;
        len = strlen(str);
        while(end < len)
        {
            while(end < len && str[end] == str[start])
            {
                end++;
            }
            s[ss++] = end - start + '0';
            s[ss++] = str[start];
            start = end;
        }
        strcpy(str, s);
        free(s);
    }
    return str;
}

49. 字母异位词分组

java解决方法:

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        int len = strs.length;
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        for(int i = 0; i < len; i++)
        {
            String str = strs[i];
            char[] array = str.toCharArray();
            //对数组进行排序
            Arrays.sort(array);
            String key = new String(array);
            //返回指定键映射到的值,如果此映射不包含键的映射,则返回new ArrayList<String>() 
             List<String> list = map.getOrDefault(key, new ArrayList<String>());
             list.add(str);
             map.put(key,list);
        }
        return new ArrayList<List<String>>(map.values());
    }
}

91. 解码方法

 java解决方法:

class Solution {
    public int numDecodings(String s) {
       int len = s.length();
       //arr初始化为0,i-1就是当前位置,i-2就是前一个位置
       int[] arr = new int[len + 1];
       arr[0] = 1;
       for(int i = 1; i < len + 1; i++)
       {
           if(s.charAt(i - 1) != '0')
           {
               arr[i] += arr[i - 1];
           }
           if(i > 1 && s.charAt(i - 2) != '0' && (10 * (s.charAt(i - 2) - '0') + (s.charAt(i - 1) - '0') < 27))
           {
               arr[i] += arr[i - 2];
           }
       }
       return arr[len];
    }
    
}

C解决方法:

int numDecodings(char * s){
    int len;
    len = strlen(s);
    //arr初始化为0,i-1就是当前位置,i-2就是前一个位置
    int *arr = (int *)calloc(len + 1, sizeof(int));
    arr[0] = 1;
    for(int i = 1; i < len + 1; i++)
    {
        if(s[i - 1] != '0')
        {
            arr[i] += arr[i - 1];
        }
        if(i > 1 && s[i - 2] != '0' && (10 * (s[i - 2] - '0') + (s[i - 1] - '0') < 27))
        {
            arr[i] += arr[i - 2];
        }
    }
    return arr[len];
}

125. 验证回文串

java解决方法:

class Solution {
    public boolean isPalindrome(String s) {
        int start = 0;
        int end = s.length() - 1;
        while(start < end)
        {
            while(start < end && !Character.isDigit(s.charAt(start)) && !Character.isLetter(s.charAt(start)))
            {
                start++;
            }
            while(start < end && !Character.isDigit(s.charAt(end)) && !Character.isLetter(s.charAt(end)))
            {
                end--;
            }
            
            if(Character.toUpperCase(s.charAt(start)) == Character.toUpperCase(s.charAt(end)))
            {
                end--;
                start++;
            }
            else
            {
                return false;
            }
        }
        return true;
    }
}

 C解决方法:

bool isPalindrome(char * s){
    int start = 0;
    int end;
    end = strlen(s) - 1;
    while(start < end)
    {
        while(start < end && !isalnum(s[start]))
        {
            start++;
        }
        while(start < end && !isalnum(s[end]))
        {
            end--;
        }
        if(toupper(s[start]) == toupper(s[end]))
        {
            end--;
            start++;
        }
        else
        {
            return false;
        }
    }
    return true;
    
}

131. 分割回文字符串

java解决方法:

class Solution {
    int n;
    boolean[][] f;
    List<List<String>> ret = new ArrayList<List<String>>();
    List<String> ans = new ArrayList<String>();
    public List<List<String>> partition(String s) {
       n = s.length();
       f = new boolean[n][n];
       //将指定的布尔值分配给指定的布尔数组的每个元素。
       for (int i = 0; i < n; ++i) {
            Arrays.fill(f[i], true);
        }
       //动态规划方法判断相对应的子串是否是回文串
       for(int i1 = n - 1; i1 >= 0; i1--)
       {
           for(int i2 = i1 + 1; i2 < n; i2++)
           {
               f[i1][i2] = (s.charAt(i1) == s.charAt(i2)) && f[i1 + 1][i2 - 1];
           }
       }
       dfs(s, 0);
       return ret;
    }
    //回溯法来获得所有的组合
    public void dfs(String s, int i)
    {
        if (i == n) {
            ret.add(new ArrayList<String>(ans));
            return;
        }
        for (int j = i; j < n; ++j) {
            if (f[i][j]) {
                //子串开始于指定beginIndex并延伸到字符索引endIndex - 1
                ans.add(s.substring(i, j + 1));
                dfs(s, j + 1);
                ans.remove(ans.size() - 1);
            }
        }
    }
}

139. 单词的拆分

java解决方法: 

我们定义 dp[i] 表示字符串 s i 个字符组成的字符串 s[0..i-1] 是否能被空格拆分成若干个字典中出现的单词。默认 i = 0 时 s 为空串。

d p[i]=d p[j] \& \& \operatorname{check}(s[j . . i-1])

其中 s[j..i-1] 表示子串 s[j..i-1] 是否出现在字典中。

public class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        Set<String> wordDictSet = new HashSet(wordDict);
        boolean[] dp = new boolean[s.length() + 1];
        //边界条件bp[0] = true表示空串且合法.
        dp[0] = true;
        for (int i = 1; i <= s.length(); i++) {
            for (int j = 0; j < i; j++) {
                //子串开始于指定beginIndex并延伸到字符索引endIndex - 1
                //bp[i2]表示前i2-1子串是否合法
                if (dp[j] && wordDictSet.contains(s.substring(j, i))) {
                    dp[i] = true;
                    //尽量保持小的间距的合法子串
                    break;
                }
            }
        }
        return dp[s.length()];
    }
}

166. 分数到小数

java解决方法: 

class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        // 转 long 计算,防止溢出
        long a = numerator;
        long b = denominator;
        // 如果本身能够整除,直接返回计算结果
        if(a % b == 0)
        {
            return String.valueOf(a / b);
        }
        StringBuilder sb = new StringBuilder();
        // 如果其一为负数,先追加负号
        if(a * b < 0)
        {
            sb.append('-');
        }
        a = Math.abs(a);
        b = Math.abs(b);
        // 计算小数点前的部分,并将余数赋值给 a
        sb.append(String.valueOf(a / b) + '.');
        a = a % b;
        Map<Long, Integer> map = new HashMap<>();
        while(a != 0)
        {
            // 记录当前余数所在答案的位置,并继续模拟除法运算
            map.put(a, sb.length());
            a *= 10;
            sb.append(a / b);
            a = a % b;
            // 如果当前余数之前出现过,则将 [出现位置 到 当前位置] 的部分抠出来(循环小数部分)
            if(map.containsKey(a))
            {
                int u = map.get(a);
                return String.format("%s(%s)",sb.substring(0,u),sb.substring(u,sb.length()));
            }
        }
        return sb.toString();
    }
}

输入格式:

1

输出格式:

"0.5"

public class MainClass {
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = in.readLine()) != null) {
            int numerator = Integer.parseInt(line);
            line = in.readLine();
            int denominator = Integer.parseInt(line);
            
            String ret = new Solution().fractionToDecimal(numerator, denominator);
            
            String out = (ret);
            
            System.out.print(out);
        }
    }
}

171. Excel 表序号

 

java解决方法:

class Solution {
    public int titleToNumber(String columnTitle) {
        int len = columnTitle.length();
        int sum = 0;
        for(int i = 0; i < len; i++)
        {
            sum += (columnTitle.charAt(i) - 'A' + 1) * Math.pow(26, len - i - 1);
        }
        return sum;
    }
}

 输入格式:"A"

输出格式:1

public class MainClass {
    public static String stringToString(String input) {
        return JsonArray.readFrom("[" + input + "]").get(0).asString();
    }
    
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = in.readLine()) != null) {
            String columnTitle = stringToString(line);
            
            int ret = new Solution().titleToNumber(columnTitle);
            
            String out = String.valueOf(ret);
            
            System.out.print(out);
        }
    }
}

179. 最大数

 java解决方法:

class Solution {
    public String largestNumber(int[] nums) {
        int n = nums.length;
        // 转换成包装类型,以便传入 Comparator 对象(此处为 lambda 表达式)
        Integer[] numsArr = new Integer[n];
        for(int i = 0; i < n; i++)
        {
            numsArr[i] = nums[i];
        }
        Arrays.sort(numsArr, (x,y)->
        {
            long sx = 10;
            long sy = 10;
            while(sx <= x)
            {
                sx *= 10;
            }
            while(sy <= y)
            {
                sy *= 10;
            }
            return (int)(sx * y + x - sy * x - y);
        });
        if(numsArr[0] == 0)
        {
            return "0";
        }
        StringBuilder ret = new StringBuilder();
        for(int i1 = 0; i1 < n; i1++)
        {
            ret.append(numsArr[i1]);
        }
        return ret.toString();
    }
}

 输入:[10,2]

输出:"210"

public class MainClass {
    public static int[] stringToIntegerArray(String input) {
        //返回一个字符串,其值为此字符串,并删除任何前导和尾随空格。
        input = input.trim();
        input = input.substring(1, input.length() - 1);
        if (input.length() == 0) {
          return new int[0];
        }
    
        String[] parts = input.split(",");
        int[] output = new int[parts.length];
        for(int index = 0; index < parts.length; index++) {
            String part = parts[index].trim();
            output[index] = Integer.parseInt(part);
        }
        return output;
    }
    
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = in.readLine()) != null) {
            int[] nums = stringToIntegerArray(line);
            
            String ret = new Solution().largestNumber(nums);
            //输出加上双引号
            String out = (ret);
            
            System.out.print(out);
        }
    }
}

277. 基本计算器

java解决方法:

class Solution {
    public int calculate(String s) {
        Stack st = new Stack();
        int len = s.length();
        //加号:将数字压入栈;
        //减号:将数字的相反数压入栈;
        //乘除号:计算数字与栈顶元素,并将栈顶元素替换为计算结果.
        //加减乘除号一次只能出现一个
        int i = 0;
        int sum = 0;
        char flag;
        //表示加减乘除类型
        //获得第一个值,并入栈
        while(i < len && s.charAt(i) != '+' && s.charAt(i) != '-' && s.charAt(i) != '*' && s.charAt(i) != '/')
        {
            while(i < len && s.charAt(i) == ' ')
            {
                i++;
            }
            while(i < len && Character.isDigit(s.charAt(i)))
            {
                sum = sum * 10 + s.charAt(i) - '0';
                i++;
            }
            while(i < len && s.charAt(i) == ' ')
            {
                i++;
            }
        }
        st.push(sum);
        sum = 0;
        
        while(i < len)
        {
            //保存符号
            flag = s.charAt(i);
            i++;
            //获得第二个值
            while(i < len && s.charAt(i) != '+' && s.charAt(i) != '-' && s.charAt(i) != '*' && s.charAt(i) != '/')
            {
                while(i < len && s.charAt(i) == ' ')
                {
                    i++;
                }
                while(i < len && Character.isDigit(s.charAt(i)))
                {
                    sum = sum * 10 + s.charAt(i) - '0';
                    i++;
                }
                while(i < len && s.charAt(i) == ' ')
                {
                    i++;
                }
            }
            if(flag == '+')
            {
                st.push(sum);
                sum = 0;
            }
            else if(flag == '-')
            {
                st.push(-sum);
                sum = 0;
            }
            else if(flag == '*')
            {
                int s1 = (int)st.pop();
                st.push(sum * s1);
                sum = 0;
            }
            else if(flag == '/')
            {
                int s1 = (int)st.pop();
                st.push((int)(s1 / sum));
                sum = 0;
            }
        }
        int total = 0;
        while(!st.empty())
        {
            total += (int)st.pop();
        }
        return total;
    }
}

输入:"3+2*2"

输出:7

public class MainClass {
    public static String stringToString(String input) {
        return JsonArray.readFrom("[" + input + "]").get(0).asString();
    }
    
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = in.readLine()) != null) {
            String s = stringToString(line);
            
            int ret = new Solution().calculate(s);
            
            String out = String.valueOf(ret);
            
            System.out.print(out);
        }
    }
}

242. 有效的字母异位词

java解决方法:

class Solution {
    public boolean isAnagram(String s, String t) {
        //排序法
        if(s.length() != t.length())
        {
            return false;
        }
        char[] ss = s.toCharArray();
        char[] tt = t.toCharArray();
        Arrays.sort(ss);
        Arrays.sort(tt);
        if(Arrays.equals(ss, tt))
        {
            return true;
        }
        return false;
    }
}

 输入:

"anagram"

"nagaram"

输出:true

public class MainClass {
    public static String stringToString(String input) {
        return JsonArray.readFrom("[" + input + "]").get(0).asString();
    }
    
    public static String booleanToString(boolean input) {
        return input ? "True" : "False";
    }
    
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = in.readLine()) != null) {
            String s = stringToString(line);
            line = in.readLine();
            String t = stringToString(line);
            
            boolean ret = new Solution().isAnagram(s, t);
            
            String out = booleanToString(ret);
            
            System.out.print(out);
        }
    }
}

344. 反转字符串

java解决方法;

class Solution {
    public void reverseString(char[] s) {
        int len = s.length;
        int start = 0;
        int end = len - 1;
        while(start < end)
        {
            char tmp;
            tmp = s[start];
            s[start] = s[end];
            s[end] = tmp;
            start++;
            end--;
        }
    }
}

 387. 字符串中的第一个唯一字符

java解决方法:

class Solution {
    public int firstUniqChar(String s) {
        int[] count = new int[26];
        for(int i = 0; i < s.length(); i++)
        {
            count[s.charAt(i) - 'a']++;
        }
        for(int i = 0; i < s.length(); i++)
        {
            if(count[s.charAt(i) - 'a'] == 1)
            {
                return i;
            }
        }
        return -1;
    }
}

395. 至少有k个重复字符的最长子串

 java解决方法:

class Solution {
    public int longestSubstring(String s, int k) {
        //ans表示最长子串的长度
        int ans = 0;
        int len = s.length();
        //cs表示字符数组
        char[] cs = s.toCharArray();
        //表示26个字母的累计个数
        int[] cnt = new int[26];
        //包含字符种类个数一种26种情况
        for(int i1 = 1; i1 < 26; i1++)
        {
            Arrays.fill(cnt, 0);
            // tot 代表 [j, i] 区间所有的字符种类数量;sum 代表满足「出现次数不少于 k」的字符种类数量
            for(int i = 0, j = 0, tot = 0, sum = 0; i < len; i++)
            {
                int u = cs[i] - 'a';
                cnt[u]++;
                // 如果添加到 cnt 之后为 1,说明字符总数tot +1
                if(cnt[u] == 1)
                {
                    tot++;
                }
                // 如果添加到 cnt 之后等于 k,说明该字符从不达标变为达标,达标数量 + 1
                if(cnt[u] == k)
                {
                    sum++;
                }
                // 当区间所包含的字符种类数量 tot 超过了当前限定的数量 p,那么我们要删除掉一些字母,即「左指针」右移
                while(tot > i1)
                {
                    int t = cs[j++] - 'a';
                    cnt[t]--;
                    // 如果添加到 cnt 之后为 0,说明字符总数-1
                    if(cnt[t] == 0)
                    {
                        tot--;
                    }
                    // 如果添加到 cnt 之后等于 k - 1,说明该字符从达标变为不达标,达标数量 - 1
                    if(cnt[t] == k - 1)
                    {
                        sum--;
                    }
                }
                // 当所有字符都符合要求,更新答案
                 if (tot == sum) ans = Math.max(ans, i - j + 1);
            }
        }
        return ans;
    }
}

 输入:

"aaabb"

3

输出:

3

public class MainClass {
    public static String stringToString(String input) {
        return JsonArray.readFrom("[" + input + "]").get(0).asString();
    }
    
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = in.readLine()) != null) {
            String s = stringToString(line);
            line = in.readLine();
            int k = Integer.parseInt(line);
            
            int ret = new Solution().longestSubstring(s, k);
            
            String out = String.valueOf(ret);
            
            System.out.print(out);
        }
    }
}

 412. Fizz Buzz

java解决方法:

class Solution {
    public List<String> fizzBuzz(int n) {
        List<String> li = new ArrayList<String>();
        for(int i = 1; i <= n; i++)
        {
            if(i % 3 == 0 && i % 5 == 0)
            {
                li.add("FizzBuzz");
            }
            else if(i % 3 == 0 && i % 5 != 0)
            {
                li.add("Fizz");
            }
            else if(i % 3 != 0 && i % 5 == 0)
            {
                li.add("Buzz");
            }
            else
            {
                li.add(String.valueOf(i));
            }
        }
        return li;
    }
}

 输入:3

输出:["1","2","Fizz"]

public class MainClass {
    public static String stringListToString(List<String> stringList) {
        StringBuilder sb = new StringBuilder("[");
        for (String item : stringList) {
            sb.append(item);
            sb.append(",");
        }
        //把最后一个逗号变为]
        sb.setCharAt(sb.length() - 1, ']');
        return sb.toString();
    }
    
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = in.readLine()) != null) {
            int n = Integer.parseInt(line);
            
            List<String> ret = new Solution().fizzBuzz(n);
            
            String out = stringListToString(ret);
            
            System.out.print(out);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身影王座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值