字符串操作问题

一、字符串基础问题

1、LeetCode709:转换成小写字母

实现函数ToLowerCase(),该函数接收一个字符串参数str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串

示例1:

输入: "Hello"
输出: "hello"

示例2:

输入: "here"
输出: "here"

示例3:

输入: "LOVELY"
输出: "lovely"

题解:

    public String toLowerCase(String str) {
        char[] charArray = new char[str.length()];
        char c;
        for (int i = 0; i < str.length(); ++i) {
            c = str.charAt(i);
            if (c >= 65 && c <= 90) {
                c = (char) (c + 32);
            }
            charArray[i] = c;
        }
        return new String(charArray);
    }

2、LeetCode58:最后一个单词的长度

给定一个仅包含大小写字母和空格的字符串,返回其最后一个单词的长度

如果不存在最后一个单词,请返回0

说明:一个单词是指由字母组成,但不包含任何空格的字符串

示例:

输入: "Hello World"
输出: 5

解析:

从字符串末尾开始向前遍历,其中主要有两种情况:

第一种情况,以字符串"Hello World"为例,从后向前遍历直到遍历到头或者遇到空格为止,即为最后一个单词"World"的长度5

第二种情况,以字符串"Hello World “为例,需要先将末尾的空格过滤掉,再进行第一种情况的操作,即认为最后一个单词为"World”,长度为5

转自:https://leetcode-cn.com/problems/length-of-last-word/solution/hua-jie-suan-fa-58-zui-hou-yi-ge-dan-ci-de-chang-d/

题解:

    public int lengthOfLastWord(String s) {
        s = s.trim();
        int start = s.lastIndexOf(" ") + 1;
        return s.substring(start).length();
    }

3、LeetCode771:宝石与石头

给定字符串J代表石头中宝石的类型,和字符串S代表你拥有的石头。S中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石

J中的字母不重复,J和S中的所有字符都是字母。字母区分大小写,因此"a"和"A"是不同类型的石头

示例1:

输入: J = "aA", S = "aAAbbbb"
输出: 3

示例2:

输入: J = "z", S = "ZZ"
输出: 0

题解:

    public int numJewelsInStones(String J, String S) {
        Set<Character> set = new HashSet<>();
        for (char j : J.toCharArray()) {
            set.add(j);
        }
        int count = 0;
        for (char s : S.toCharArray()) {
            if (set.contains(s)) count++;
        }
        return count;
    }

4、LeetCode387:字符串中的第一个唯一字符

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回-1

案例:

s = "leetcode"
返回 0

s = "loveleetcode"
返回 2

题解:

    public int firstUniqChar(String s) {
        HashMap<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < s.length(); ++i) {
            map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
        }
        for (int i = 0; i < s.length(); ++i) {
            if (map.get(s.charAt(i)) == 1) {
                return i;
            }
        }
        return -1;
    }

二、字符串操作问题

1、LeetCode14:最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀

如果不存在公共前缀,返回空字符串 “”

示例1:

输入: ["flower","flow","flight"]
输出: "fl"

示例2:

输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀

题解:

    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() || strs[j].charAt(i) != c) {
                    return strs[0].substring(0, i);
                }
            }
        }
        return strs[0];
    }

2、LeetCode344:反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组char[]的形式给出

示例1:

输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例2:

输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

题解:

    public void reverseString(char[] s) {
        if (s == null) return;
        for (int i = 0, j = s.length - 1; i < j; ++i, --j) {
            char tmp = s[i];
            s[i] = s[j];
            s[j] = tmp;
        }
    }

3、LeetCode541:反转字符串 II

给定一个字符串和一个整数k,你需要对从字符串开头算起的每隔2k个字符的前k个字符进行反转。如果剩余少于k 个字符,则将剩余的所有全部反转。如果有小于2k但大于或等于k个字符,则反转前k个字符,并将剩余的字符保持原样

示例:

输入: s = "abcdefg", k = 2
输出: "bacdfeg"

题解:

    public String reverseStr(String s, int k) {
        char[] chars = s.toCharArray();
        for (int start = 0; start < chars.length; start += 2 * k) {
            int i = start, j = Math.min(start + k - 1, chars.length - 1);
            while (i < j) {
                char tmp = chars[i];
                chars[i++] = chars[j];
                chars[j--] = tmp;
            }
        }
        return new String(chars);
    }

4、LeetCode151:翻转字符串里的单词

给定一个字符串,逐个翻转字符串中的每个单词

示例1:

输入: "the sky is blue"
输出: "blue is sky the"

示例 2:

输入: "  hello world!  "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括

示例3:

输入: "a good   example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个

题解:

    public String reverseWords(String s) {
        String[] words = s.trim().split(" +");
        Collections.reverse(Arrays.asList(words));
        return String.join(" ", words);
    }

5、LeetCode557:反转字符串中的单词 III

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序

示例1:

输入: "Let's take LeetCode contest"
输出: "s'teL ekat edoCteeL tsetnoc" 

题解:

    public String reverseWords(String s) {
        String[] words = s.split(" ");
        StringBuilder result = new StringBuilder();
        for (String word : words) {
            result.append(new StringBuilder(word).reverse().toString() + " ");
        }
        return result.toString().trim();
    }

6、LeetCode917:仅仅反转字母

给定一个字符串S,返回反转后的字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转

示例1:

输入:"ab-cd"
输出:"dc-ba"

示例2:

输入:"a-bC-dEf-ghIj"
输出:"j-Ih-gfE-dCba"

示例3:

输入:"Test1ng-Leet=code-Q!"
输出:"Qedo1ct-eeLg=ntse-T!"

题解:

    public String reverseOnlyLetters(String s) {
        StringBuilder result = new StringBuilder();
        int j = s.length() - 1;
        for (int i = 0; i < s.length(); ++i) {
            if (Character.isLetter(s.charAt(i))) {
                while (!Character.isLetter(s.charAt(j)))
                    j--;
                result.append(s.charAt(j--));
            } else {
                result.append(s.charAt(i));
            }
        }

        return result.toString();
    }

三、异位词问题

1、LeetCode242:有效的字母异位词

给定两个字符串s和t,编写一个函数来判断t是否是s的字母异位词

示例1:

输入: s = "anagram", t = "nagaram"
输出: true

示例2:

输入: s = "rat", t = "car"
输出: false

题解:

    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) return false;
        int[] array = new int[26];
        for (int i = 0; i < s.length(); ++i) {
            array[s.charAt(i) - 'a']++;
            array[t.charAt(i) - 'a']--;
        }
        for (int i : array) {
            if (i != 0) return false;
        }
        return true;
    }

2、LeetCode49:字母异位词分组

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串

示例:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

题解:

    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for (String str : strs) {
            char[] array = str.toCharArray();
            Arrays.sort(array);
            String key = String.valueOf(array);
            if (map.containsKey(key)) {
                map.get(key).add(str);
            } else {
                List<String> tmp = new ArrayList<>();
                tmp.add(str);
                map.put(key, tmp);
            }
        }
        return new ArrayList<List<String>>(map.values());
    }

3、LeetCode438:找到字符串中所有字母异位词

给定一个字符串s和一个非空字符串p,找到s中所有是p的字母异位词的子串,返回这些子串的起始索引

字符串只包含小写英文字母,并且字符串s和p的长度都不超过20100

说明:

字母异位词指字母相同,但排列不同的字符串

不考虑答案输出的顺序

示例1:

输入:
s: "cbaebabacd" p: "abc"
输出:
[0, 6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词
起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词

示例2:

输入:
s: "abab" p: "ab"
输出:
[0, 1, 2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的字母异位词
起始索引等于 1 的子串是 "ba", 它是 "ab" 的字母异位词
起始索引等于 2 的子串是 "ab", 它是 "ab" 的字母异位词

题解:

四、回文串问题

1、LeetCode125:验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写

示例1:

输入: "A man, a plan, a canal: Panama"
输出: true

示例2:

输入: "race a car"
输出: false

题解:

    public boolean isPalindrome(String s) {
        int i = 0, j = s.length() - 1;
        while (i < j) {
            while (i < j && !Character.isLetterOrDigit(s.charAt(i))) i++;
            while (i < j && !Character.isLetterOrDigit(s.charAt(j))) j--;
            if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j)))
                return false;
            i++;
            j--;
        }
        return true;
    }

2、LeetCode680:验证回文字符串 Ⅱ

给定一个非空字符串s,最多删除一个字符。判断是否能成为回文字符串

示例1:

输入: "aba"
输出: true

示例2:

输入: "abca"
输出: true
解释: 你可以删除c字符

题解:

    public boolean validPalindrome(String s) {
        char[] chars = s.toCharArray();
        int i = 0;
        int j = chars.length - 1;
        //双指针循环找出不等于的字符索引
        while (i < j && chars[i] == chars[j]) {
            i++;
            j--;
        }
        //删除左边循环判断
        if (isValid(chars, i + 1, j)) return true;
        //删除右边循环判断
        if (isValid(chars, i, j - 1)) return true;
        //如果上面都是false,那么结果肯定是false
        return false;
    }

    //验证是否是回文
    private boolean isValid(char[] chars, int i, int j) {
        while (i < j) {
            if (chars[i++] != chars[j--]) {
                return false;
            }
        }
        return true;
    }

3、LeetCode5:最长回文子串

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

示例1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案

示例2:

输入: "cbbd"
输出: "bb"

题解:

    public String longestPalindrome(String s) {
        int n = s.length();
        String result = "";
        boolean[][] dp = new boolean[n][n];
        for (int i = n - 1; i >= 0; --i) {
            for (int j = i; j < n; ++j) {
                dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i < 2 || dp[i + 1][j - 1]);
                if (dp[i][j] && j - i + 1 > result.length()) {
                    result = s.substring(i, j + 1);
                }
            }
        }
        return result;
    }
发布了177 篇原创文章 · 获赞 407 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_40378034/article/details/103446030