0
点赞
收藏
分享

微信扫一扫

leetcode 763 : 划分字母区间

目标践行者 2022-02-02 阅读 73
leetcode

leetcode 763 : 划分字母区间

字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。

示例:

输入:S = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca", "defegde", "hijhklij"。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。

提示:

  • S的长度在[1, 500]之间。

  • S只包含小写字母 'a''z'

Related Topics

贪心

哈希表

双指针字符串

思路 1:

  • 第一步,先把每一个字符的最大值保存到hashmap中。

  • 第二步,每遍历一个字符,跟这个区间的内部的最大下标比较,直到将这个区间内的字符找完为止。

    public List<Integer> partitionLabels(String s) {
        HashMap<Character,Integer> map = new HashMap<>();
        ArrayList<Integer> result = new ArrayList<>();
        //保持每一个字母的最大下标
        for(int i = 0 ; i < s.length();i++){
            map.put(s.charAt(i),i);
        }
        //因为map里面存储的是最大下标
        //每遍历一个字符 都更新这个最大值 保证同一个字母出现在同一个区间
    ​
        int start = 0;
        int end = 0;
        for(int i = 0; i < s.length();i++){
            end = Math.max(end,map.get(s.charAt(i)));
            if(i == end){ //说明这个区间内已经计算完毕
                result.add(end - start + 1);
                end++;
                start = end;
            }
        }
        return result;
    }
    解答成功:
                执行耗时:8 ms,击败了19.79% 的Java用户
                内存消耗:41.1 MB,击败了5.02% 的Java用户

思路2 :

由于只有小写字符,使用hashmap的话,存取计算哈希值,效率不如直接使用一个长度26的数组。

public List<Integer> partitionLabels(String s) {
    int[] indexs = new int[26];
    ArrayList<Integer> result = new ArrayList<>();
    //保持每一个字母的最大下标
    //int length = s.length();
    for(int i = 0 ; i <s.length();i++){
        indexs[s.charAt(i) - 'a'] = i;
    }
    //因为map里面存储的是最大下标
    //每遍历一个字符 都更新这个最大值 保证同一个字母出现在同一个区间
​
    int start = 0;
    int end = 0;
    for(int i = 0; i < s.length();i++){
        end = Math.max(end,indexs[s.charAt(i)-'a']);
        if(i == end){ //说明这个区间内已经计算完毕
            result.add(end - start + 1);
            end++;
            start = end;
        }
    }
    return result;
}
执行耗时:4 ms,击败了56.85% 的Java用户
            内存消耗:40.2 MB,击败了5.02% 的Java用户

思路3:

将s.length() 换成length时间效率有些许提高。

public List<Integer> partitionLabels(String s) {
    int[] indexs = new int[26];
    ArrayList<Integer> result = new ArrayList<>();
    //保持每一个字母的最大下标
    int length = s.length();
    for(int i = 0 ; i <length;i++){
        indexs[s.charAt(i) - 'a'] = i;
    }
    //因为map里面存储的是最大下标
    //每遍历一个字符 都更新这个最大值 保证同一个字母出现在同一个区间
​
    int start = 0;
    int end = 0;
    for(int i = 0; i < length;i++){
        end = Math.max(end,indexs[s.charAt(i)-'a']);
        if(i == end){ //说明这个区间内已经计算完毕
            result.add(end - start + 1);
            end++;
            start = end;
        }
    }
    return result;
}
解答成功:
            执行耗时:2 ms,击败了98.98% 的Java用户
            内存消耗:39.8 MB,击败了5.02% 的Java用户

思路4:

leetcode评论区看到,找到每一个字母的区间范围,这个题就变成合并区间范围这个题(第56题)。

但这个思路时间复杂度应该挺高的。 但想法确实不错。

举报

相关推荐

0 条评论