LeetCode刷题之字符串

1221. 分割平衡字符串

在一个「平衡字符串」中,'L' 和 'R' 字符的数量是相同的。
给出一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。
返回可以通过分割得到的平衡字符串的最大数量。

示例 1:
输入:s = "RLRRLLRLRL"
输出:4
解释:s 可以分割为 "RL", "RRLL", "RL", "RL", 每个子字符串中都包含相同数量的 'L' 和 'R'。

示例 2:
输入:s = "RLLLLRRRLR"
输出:3
解释:s 可以分割为 "RL", "LLLRRR", "LR", 每个子字符串中都包含相同数量的 'L' 和 'R'。

题解:
class Solution {
        public int balancedStringSplit(String s) {
        String restStr = s;
        ArrayList<String> list = new ArrayList<>();
        while (restStr.length()>0) {
            restStr = getPinghengStr(restStr)[1];  //获取剩余字符串循环处理
            list.add(getPinghengStr(restStr)[0]);  //存储各个生成的平衡字符串
        }

        return list.size();
    }

    /**
     * 传入一个字符串,截取平衡字符串,同时返回剩余字符串
     * @param str
     * @return
     */
    private String[] getPinghengStr(String str) {
        String jugeStr;
        for (int i=1;i<str.length();i++) {
            jugeStr = str.substring(0, i);

            //判断R和L出现的次数是否相等
            int rCount = 0; //R出现的次数
            int lCount = 0; //L出现的次数
            for (int j=0;j<jugeStr.length();j++) {
                if (jugeStr.charAt(j) == 'R') {
                    rCount++;
                } else if (jugeStr.charAt(j) == 'L') {
                    lCount++;
                }
            }
            if (rCount == lCount) {
                //判断是平衡字符串,返回结果
                return new String[]{jugeStr, str.substring(i)};
            } else {
                //继续循环加长字符判断
                continue;
            }
        }

        return new String[]{"", ""};
    }
}
1436. 旅行终点站

给你一份旅游线路图,该线路图中的旅行线路用数组 paths 表示,其中 paths[i] = [cityAi, cityBi] 表示该线路将会从 cityAi 直接前往 cityBi 。请你找出这次旅行的终点站,即没有任何可以通往其他城市的线路的城市。

题目数据保证线路图会形成一条不存在循环的线路,因此只会有一个旅行终点站。

示例 1:
输入:paths = [["London","New York"],["New York","Lima"],["Lima","Sao Paulo"]]
输出:"Sao Paulo"
解释:从 "London" 出发,最后抵达终点站 "Sao Paulo" 。本次旅行的路线是 "London" -> "New York" -> "Lima" -> "Sao Paulo" 。

示例 2:
输入:paths = [["B","C"],["D","B"],["C","A"]]
输出:"A"
解释:所有可能的线路是:
"D" -> "B" -> "C" -> "A".
"B" -> "C" -> "A".
"C" -> "A".
"A".
显然,旅行终点站是 "A" 。

题解:
class Solution {

    public String destCity(List<List<String>> paths) {
        //思路,将每一个地点存入map中,出现一次值+1,所以整个路径的起点和终点次数是1,途径地点次数为2,最后返回终点
        //区分起点和终点:给键字符串加一个< >符号, <表示起点, >表示结束点
        //用另一个map存每个字符串添加时是起点还是终点的标识
        Map<String,Integer> record = new HashMap<>();
        Map<String, Integer> startEnd = new HashMap<>();
        List<String> curPath;

        for (int i=0;i<paths.size();i++) {
            curPath = paths.get(i);

            for (int j=0;j<curPath.size();j++) {
                //字符串次数+1
                if (!record.containsKey(curPath.get(j))) {
                    record.put(curPath.get(j), 1);

                    startEnd.put(curPath.get(j), j%2);  //是起点,存0,是结束点,存1
                } else {
                    record.put(curPath.get(j), record.get(curPath.get(j)) + 1);
                }
            }
        }

        Set<Map.Entry<String, Integer>> entries = record.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            if (entry.getValue() == 1 && startEnd.get(entry.getKey()) == 1) {
                //出现一次的结束点即为旅行的终点
                return entry.getKey();
            }
        }

        return "";
    }

}
709. 转换成小写字母

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

示例 1:
输入: "Hello"
输出: "hello"

示例 2:
输入: "here"
输出: "here"

题解:
class Solution {
    public String toLowerCase(String str) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i=0;i<str.length();i++) {
            if (str.charAt(i) >= 'A' && str.charAt(i) <= 'Z') {
                stringBuilder.append(upToLow(str.charAt(i)));  //大写字母先转小写,再添加
            } else {
                stringBuilder.append(str.charAt(i));  //小写字母直接添加
            }
        }
        return stringBuilder.toString();
    }

    /**
     * 大写字母转小写
     * @param c
     * @return
     */
    public char upToLow(char c) {
        if (c >= 'A' && c <= 'Z') {
            //判断c为大写字母
            c += 32;
        }
        return c;
    }
}
804. 唯一摩尔斯密码词

国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: "a" 对应 ".-", "b" 对应 "-...", "c" 对应 "-.-.", 等等。

为了方便,所有26个英文字母对应摩尔斯密码表如下:

[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]
给定一个单词列表,每个单词可以写成每个字母对应摩尔斯密码的组合。例如,"cab" 可以写成 "-.-..--...",(即 "-.-." + ".-" + "-..." 字符串的结合)。我们将这样一个连接过程称作单词翻译。

返回我们可以获得所有词不同单词翻译的数量。

例如:
输入: words = ["gin", "zen", "gig", "msg"]
输出: 2
解释:
各单词翻译如下:
"gin" -> "--...-."
"zen" -> "--...-."
"gig" -> "--...--."
"msg" -> "--...--."
共有 2 种不同翻译, "--...-." 和 "--...--.".

题解:
class Solution {
    public int uniqueMorseRepresentations(String[] words) {
        //思路:将字符串数组每个字符串,去每个字符对应表里获取该字符串的摩斯码串,
        //将各个摩斯码字符串存入set中去重,set的长度就是不同单词的数量

        String[] morseCodeTable = new String[]{".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
        Set<String> codes = new HashSet<>();
        for (String word : words) {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i=0;i<word.length();i++) {
                String psd = morseCodeTable[word.charAt(i)-'a'];
                stringBuilder.append(psd);  //当前字符在摩尔斯码表中的符号
            }
            codes.add(stringBuilder.toString());
        }

        return codes.size();
    }
}
557. 反转字符串中的单词 III

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

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

题解:
class Solution {
    public String reverseWords(String s) {
        String[] subStrArray = s.split(" ");
        //将每一个子字符串倒转
        StringBuilder stringBuilder = new StringBuilder();
        for (int i=0;i<subStrArray.length;i++) {
            stringBuilder.delete(0, stringBuilder.length()-1);  //清楚数据重复使用
            subStrArray[i] = stringBuilder.append(subStrArray[i]).reverse().toString();
        }

        for (int i=0;i<subStrArray.length;i++) {
            stringBuilder.append(subStrArray[i] + " ");
        }

        return stringBuilder.deleteCharAt(stringBuilder.length()-1).toString();
    }
}
344. 反转字符串

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

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

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

题解:
class Solution {
    public void reverseString(char[] s) {
        //原地倒转字符数组,采用对应位置交换值的方法
        int start = 0;
        int end = s.length-1;
        //要交换的次数
        char temp;
        while (start < end) {
            temp = s[start];
            s[start] = s[end];
            s[end] = temp;

            //位置往中间靠
            start++;
            end--;
        }

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

给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

示例 1:
输入: s1 = "abc", s2 = "bca"
输出: true

示例 2:
输入: s1 = "abc", s2 = "bad"
输出: false

题解:
class Solution {
    public boolean CheckPermutation(String s1, String s2) {
        //思路:遍历s1中每一个字符,从s2中从左到右依次找这个字符,找到就将该字符从s2中删去,然后遍历下一个字符,直到遍历完
        //如果中途出现找不到的字符,说明不能变成另一个字符串。

        //首先:第一步,s1和s2长度需要相等
        if (s1.length() != s2.length()) {
            return false;
        }

        String temp = s2;
        for (int i=0;i<s1.length();i++) {
            int pos = temp.indexOf(s1.charAt(i));  //找到这个字符的下标,将其从s2中删除,找不到返回-1
            if (pos == -1) {
                return false;
            } else {
                temp = strRemoveChar(temp, pos);
            }
        }
        return true;
    }

        /**
     * 删除字符串指定位置的字符
     * @param string
     * @param pos
     * @return
     */
    public String strRemoveChar(String string, int pos) {
        return string.substring(0, pos) + string.substring(pos+1);
    }

}
1189. “气球” 的最大数量

给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 "balloon"(气球)。

字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 "balloon"。

示例 1:
输入:text = "nlaebolko"
输出:1

示例 2:
输入:text = "loonbalxballpoon"
输出:2

示例 3:
输入:text = "leetcode"
输出:0

题解:
class Solution {
    public int maxNumberOfBalloons(String text) {
        //思路:遍历balloon单词每个字符,从text中找这个字符,找到一个就删除,继续下一个字符。
        //一个balloon单词找完,就循环找下一个单词,知道从text中找不到某个字符,获取当前找到的完整balloon个数

        String wordBalloon = "balloon";
        String tempText = text;
        int spellCount = 0;  //拼出完整balloon单词的次数
        while (true) {
            for (int i=0;i<wordBalloon.length();i++) {
                char curChar = wordBalloon.charAt(i);
                int pos = tempText.indexOf(curChar);
                if (pos == -1) {
                    //没有找到该字符
                    return spellCount;
                } else {
                    tempText = strRemoveChar(tempText, pos);
                }
            }

            //一个单词循环完毕,单词量+1
            spellCount++;
        }
    }

        /**
     * 删除字符串指定位置的字符
     * @param string
     * @param pos
     * @return
     */
    public String strRemoveChar(String string, int pos) {
        return string.substring(0, pos) + string.substring(pos+1);
    }
}
1408. 数组中的字符串匹配

给你一个字符串数组 words ,数组中的每个字符串都可以看作是一个单词。请你按 任意 顺序返回 words 中是其他单词的子字符串的所有单词。

如果你可以删除 words[j] 最左侧和/或最右侧的若干字符得到 word[i] ,那么字符串 words[i] 就是 words[j] 的一个子字符串。

示例 1:
输入:words = ["mass","as","hero","superhero"]
输出:["as","hero"]
解释:"as" 是 "mass" 的子字符串,"hero" 是 "superhero" 的子字符串。
["hero","as"] 也是有效的答案。

示例 2:
输入:words = ["leetcode","et","code"]
输出:["et","code"]
解释:"et" 和 "code" 都是 "leetcode" 的子字符串。

示例 3:
输入:words = ["blue","green","bu"]
输出:[]

题解:
class Solution {
    public List<String> stringMatching(String[] words) {
        //思路:遍历words数组,若其它字符串包含该字符串,则这个字符串为子串输出

        Set<String> subStr = new HashSet<>();  //记录子字符串,注意这个坑,不能记录重复,所以用set来存一遍
        for (int i=0;i<words.length;i++) {
            String curWord = words[i];

            for (int j=0;j<words.length;j++) {
                if (!words[j].equals(curWord) && words[j].contains(curWord)) {
                    subStr.add(curWord);
                }
            }
        }

        return new ArrayList<>(subStr);
    }
}

找出字符串中第一个匹配项的下标

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。

题解:
class Solution {
    public int strStr(String haystack, String needle) {
        int needleLength = needle.length();
        if (!haystack.contains(needle)) {
            //不包含,直接返回-1
            return -1;
        } else {
            //包含
            for (int i=0;i<=haystack.length()-needleLength;i++) {
                String compareStr = haystack.substring(i, i+needleLength);
                if (needle.equals(compareStr)) {
                    return i;
                }
            }
            return -1;
        }
    }
}

最长公共前缀

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

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

题解:
class Solution {
    /**
     * 最长公共前缀
     *
     * 思路:取出最短的一个字符串,将里面依次字符取出,和其他字符比较
     * 相同,则添加到公共字符串里,如果不相同,则返回当前公共字符串
     */
    public static String longestCommonPrefix(String[] strs) {
         if (strs.length == 1) {
            return strs[0];
        }
        StringBuilder stringBuilder = new StringBuilder();
        int shortestStrLeng = strs[0].length();
        int shortestStrPos = 0;
        for (int i=0;i<strs.length;i++) {
            if (strs[i].length() == 0) {
                return "";
            }
            if (strs[i].length() < shortestStrLeng) {
                shortestStrLeng = strs[i].length();
                shortestStrPos = i;
            }
        }

        for (int i=0;i<strs[shortestStrPos].length();i++) {
            ///将所有字符串的依次i个位置字符拿来比较是否相同
            char cr = strs[shortestStrPos].charAt(i);
            for (int j=0;j<strs.length;j++) {
                if (cr != strs[j].charAt(i)) {
                    return stringBuilder.toString();
                }
            }
            stringBuilder.append(cr);
        }
        return stringBuilder.toString();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342