计算连续字符的个数

1446. 连续字符

题目描述:

给你一个字符串 s ,字符串的「能量」定义为:只包含一种字符的最长非空子字符串的长度。请你返回字符串的能量。

提示:

  • 1 <= s.length <= 500
  • s 只包含小写英文字母。

示例 1:
输入:s = “leetcode”
输出:2
解释:子字符串 “ee” 长度为 2 ,只包含字符 ‘e’ 。

示例 2:
输入:s = “abbcccddddeeeeedcba”
输出:5
解释:子字符串 “eeeee” 长度为 5 ,只包含字符 ‘e’ 。

示例 3:
输入:s = “triplepillooooow”
输出:5

示例 4:
输入:s = “hooraaaaaaaaaaay”
输出:11

示例 5:
输入:s = “tourist”
输出:1

代码如下:

class Solution {
    
    
    public int maxPower(String s) {
    
    
        int n = s.length();
        int ptr = 0;
        int ans = Integer.MIN_VALUE;
        while (ptr < n) {
    
    
            char ch = s.charAt(ptr);
            int count = 0;
            while (ptr < n && s.charAt(ptr) == ch) {
    
    
                ptr++;
                count++;
            }
            ans = Math.max(ans, count);
        }
        return ans;
    }
}

执行结果:
在这里插入图片描述

830. 较大分组的位置

题目描述:

在一个由小写字母构成的字符串 s 中,包含由一些连续的相同字符所构成的分组。
例如,在字符串 s = “abbxxxxzyy” 中,就含有 “a”, “bb”, “xxxx”, “z” 和 “yy” 这样的一些分组。分组可以用区间 [start, end] 表示,其中 start 和 end 分别表示该分组的起始和终止位置的下标。上例中的 “xxxx” 分组用区间表示为 [3,6] 。我们称所有包含大于或等于三个连续字符的分组为 较大分组 。找到每一个 较大分组 的区间,按起始位置下标递增顺序排序后,返回结果。

提示:

  • 1 <= s.length <= 1000
  • s 仅含小写英文字母

示例 1:
输入:s = “abbxxxxzzy”
输出:[[3,6]]
解释:“xxxx” 是一个起始于 3 且终止于 6 的较大分组。

示例 2:
输入:s = “abc”
输出:[]
解释:“a”,“b” 和 “c” 均不是符合要求的较大分组。

示例 3:
输入:s = “abcdddeeeeaabbbcd”
输出:[[3,5],[6,9],[12,14]]
解释:较大分组为 “ddd”, “eeee” 和 “bbb”

示例 4:
输入:s = “aba”
输出:[]

代码如下:

class Solution {
    
    
    public List<List<Integer>> largeGroupPositions(String s) {
    
    
        List<List<Integer>> list = new ArrayList<>();
        int n = s.length();
        int ptr = 0;
        while (ptr < n) {
    
    
            int count = 0;
            char ch = s.charAt(ptr);
            List<Integer> arr = new ArrayList<>();
            while (ptr < n && ch == s.charAt(ptr)) {
    
    
                ptr++;
                count++;
            }
            if (count >= 3) {
    
    
                arr.add(ptr - count);
                arr.add(ptr - 1);
                list.add(arr);
            }
        }
        return list;
    }
}

执行结果:
在这里插入图片描述

面试题 01.06. 字符串压缩

题目描述:

字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2b1c5a3。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。

示例1:
输入:“aabcccccaaa”
输出:“a2b1c5a3”

示例2:
输入:“abbccd”
输出:“abbccd”
解释:“abbccd"压缩后为"a1b2c2d1”,比原字符串长度更长。

代码如下:

class Solution {
    
    
    public String compressString(String s) {
    
    
        int n = s.length();
        int ptr = 0;
        StringBuilder SB = new StringBuilder();
        while (ptr < n) {
    
    
            char ch = s.charAt(ptr);
            int count = 0;
            while (ptr < n && s.charAt(ptr) == ch) {
    
    
                ptr++;
                count++;
            }
            SB.append(ch);
            SB.append(count);
        }
        String str = SB.toString();
        int m = str.length();
        return m >= n ? s : str;
    }
}

执行结果:
在这里插入图片描述

38. 外观数列

题目描述:

给定一个正整数 n ,输出外观数列的第 n 项。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

你可以将其视作是由递归公式定义的数字字符串序列:

  • countAndSay(1) = “1”
  • countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。

前五项如下:

  1. 1
  2. 11
  3. 21
  4. 1211
  5. 111221

第一项是数字 1
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 “11”
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 “21”
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 “1211”
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 “111221”
要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。

提示:
1 <= n <= 30

示例 1:
输入:n = 1
输出:“1”
解释:这是一个基本样例。

示例 2:
输入:n = 4
输出:“1211”
解释:
countAndSay(1) = “1”
countAndSay(2) = 读 “1” = 一 个 1 = “11”
countAndSay(3) = 读 “11” = 二 个 1 = “21”
countAndSay(4) = 读 “21” = 一 个 2 + 一 个 1 = “12” + “11” = “1211”

代码如下:

class Solution {
    
    
    public String countAndSay(int n) {
    
    
        String[] str = new String[n];
        str[0] = "1";
        if (n == 1) {
    
    
            return str[0];
        }
        for (int i = 1; i < n; i++) {
    
    
            int len = str[i - 1].length();
            int ptr = 0;
            StringBuilder sb = new StringBuilder();
            while (ptr < len) {
    
    
                char ch = str[i - 1].charAt(ptr);
                int count = 0;
                while (ptr < len && ch == str[i - 1].charAt(ptr)) {
    
    
                    ptr++;
                    count++;
                }
                sb.append(String.valueOf(count));
                sb.append(ch);
            }
            str[i] = sb.toString();
        }
        return str[n - 1];
    }
}

执行结果:
在这里插入图片描述

443. 压缩字符串

题目描述:

给定一组字符,使用原地算法将其压缩。压缩后的长度必须始终小于或等于原数组长度。数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。在完成原地修改输入数组后,返回数组的新长度。

进阶:
你能否仅使用O(1) 空间解决问题?

提示:
所有字符都有一个ASCII值在[35, 126]区间内。
1 <= len(chars) <= 1000。

示例 1:
输入:
[“a”,“a”,“b”,“b”,“c”,“c”,“c”]

输出:
返回 6 ,输入数组的前 6 个字符应该是:[“a”,“2”,“b”,“2”,“c”,“3”]

说明:
“aa” 被 “a2” 替代。“bb” 被 “b2” 替代。“ccc” 被 “c3” 替代。

示例 2:
输入:
[“a”]

输出:
返回 1 ,输入数组的前 1 个字符应该是:[“a”]

解释:
没有任何字符串被替代。

示例 3:
输入:
[“a”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”]

输出:
返回 4 ,输入数组的前4个字符应该是:[“a”,“b”,“1”,“2”]。

解释:
由于字符 “a” 不重复,所以不会被压缩。“bbbbbbbbbbbb” 被 “b12” 替代。
注意每个数字在数组中都有它自己的位置。

代码如下:

class Solution {
    
    
    public int compress(char[] chars) {
    
    
        int n = chars.length;
        int ptr = 0;
        int k = 0;
        while (ptr < n) {
    
    
            char ch = chars[ptr];
            int count = 0;
            while (ptr < n && ch == chars[ptr]) {
    
    
                ptr++;
                count++;
            }
            if (count == 1) {
    
    
                chars[k++] = ch;
            } else {
    
    
                chars[k++] = ch;
                String s = String.valueOf(count);
                int len = s.length();
                for (int i = 0; i < len; i++) {
    
    
                    chars[k++] = s.charAt(i);
                }
            }
        }
        return k;
    }
}

执行结果:
在这里插入图片描述

925. 长按键入

题目描述:

你的朋友正在使用键盘输入他的名字 name。偶尔,在键入字符 c 时,按键可能会被长按,而字符可能被输入 1 次或多次。

你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),那么就返回 True。

提示:

  • name.length <= 1000
  • typed.length <= 1000
  • name 和 typed 的字符都是小写字母。

示例 1:
输入:name = “alex”, typed = “aaleex”
输出:true
解释:‘alex’ 中的 ‘a’ 和 ‘e’ 被长按。

示例 2:
输入:name = “saeed”, typed = “ssaaedd”
输出:false
解释:‘e’ 一定需要被键入两次,但在 typed 的输出中不是这样。

示例 3:
输入:name = “leelee”, typed = “lleeelee”
输出:true

示例 4:
输入:name = “laiden”, typed = “laiden”
输出:true
解释:长按名字中的字符并不是必要的。

代码如下:

class Solution {
    
    
    public boolean isLongPressedName(String name, String typed) {
    
    
        int m = name.length();
        int n = typed.length();
        int ptr1 = 0;
        int ptr2 = 0;
        while (ptr1 < m && ptr2 < n) {
    
    
            int count1 = 0;
            int count2 = 0;
            char ch1 = name.charAt(ptr1);
            char ch2 = typed.charAt(ptr2);
            while (ptr1 < m && ch1 == name.charAt(ptr1)) {
    
    
                ptr1++;
                count1++;
            }
            while (ptr2 < n && ch2 == typed.charAt(ptr2)) {
    
    
                ptr2++;
                count2++;
            }
            if (ch1 != ch2 || count1 > count2) {
    
    
                return false;
            }
        }
        return ptr1 == m && ptr2 == n;
    }
}

执行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/FYPPPP/article/details/114489722