763. 划分字母区间

题目:

思路:

【0】依据题目可得两个条件

1)同一个字母的必须在一个片段内
2)将所有划分结果按顺序连接,得到的字符串仍然是 s (也就是位置顺序不能变)

 

【1】利用数量个数来进行贪心

【2】利用下标位置来进行贪心

代码展示:

【1】利用数量个数来进行贪心

//时间1 ms 击败 100%
//内存40.1 MB 击败 60.1%
class Solution {
    // 利用数量个数的方式来进行分割(有点儿类似贪心的思维)
    public List<Integer> partitionLabels(String s) {
        int[] count = new int[26];
        char[] data = s.toCharArray();
        for (char c : data){
            count[c - 'a']++;
        }

        List<Integer> res = new ArrayList<>();
        int curCount = 0 , part = 0;
        // 如果是想要取出片段字符串的话可以用buf来作为临时存储 , 
        // 如果只为了数量的话就用上面的 part 临时变量即可
        // StringBuilder buf = new StringBuilder();
        for (int i = data.length-1; i >= 0 ; i--){
            // 获取当前字符
            char c = data[i];
            // 如果当前字符是没有取出来过的
            if (count[c - 'a'] > 0){
                // 拿出它的个数加入到需要填充的数量中
                curCount += count[c - 'a'];
                // 将记录的个数置为0,表示已经取出来过
                count[c - 'a'] = 0;
            }
            // 需要填充的数据-1
            // buf.insert(0,c);
            part++;
            curCount--;
            // 表示填充进去的数据在前面的片段中不会出现了,这时候可以作为一个分割节点
            if (curCount == 0 || i == 0){
                // System.out.println(buf.toString() + " 个数:"+buf.length());
                // 进行重置临沭存储地址
                // buf = new StringBuilder();
                res.add(0,part);
                part = 0;
            }
        }
        return res;
    }
}

【2】利用下标位置来进行贪心

//时间3 ms 击败 74.70%
//内存39.8 MB 击败 95.16%
//时间复杂度:O(n),其中 n 是字符串的长度。
//需要遍历字符串两次,第一次遍历时记录每个字母最后一次出现的下标位置,第二次遍历时进行字符串的划分。
//空间复杂度:O(1)。这道题中,字符串只包含小写字母,因此 O(26) = O(1)。
class Solution {
    /**
     * 利用下标来作为贪心的记录
     * 如填入 s = "ababcbacadefegdehijhklij";
     * 那么 last = [8, 5, 7, 14, 15, 11, 13, 19, 22, 23, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
     * last 明显是记录每个字符出现的最后位置
     * 依据条件 同一个字符需要在同一个片段 ,那么为了保证a都在同一片段所以最小的片段大小就是要到下标为8的地方
     * 同理 如果在这个过程中 b 也纳入片段 则会同步刷新 片段大小的最大下标
     * @param s
     * @return
     */
    public List<Integer> partitionLabels(String s) {
        int[] last = new int[26];
        int length = s.length();
        for (int i = 0; i < length; i++) {
            last[s.charAt(i) - 'a'] = i;
        }
        List<Integer> partition = new ArrayList<Integer>();
        int start = 0, end = 0;
        for (int i = 0; i < length; i++) {
            end = Math.max(end, last[s.charAt(i) - 'a']);
            if (i == end) {
                partition.add(end - start + 1);
                start = end + 1;
            }
        }
        return partition;
    }
}
posted @ 2023-08-04 16:28  忧愁的chafry  阅读(9)  评论(0编辑  收藏  举报