Leetcode 763 划分字母区间

2023-12-27 17:37:42

题意理解:

????????要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中

????????注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是?s?。

????????返回一个表示每个字符串片段的长度的列表。

????????输入:s = "ababc bacad efeg"
????????输出:[9,6]

? ? ? ? 划分的结果是当前片段内的字母不会出现在其他片段里? ? ?

解题思路

? ? ? ? 总是记录每个字母的最后出现的位置。则每个元素到其在s中出现的最后位置形成区间。

? ? ? ? 我们的目标是:同一个元素总是出现在一个片段里。

? ? ? ? 所以每个元素的出现区间总是包括在一个划分里

? ? ? ? 则该题就变成了一个区间重叠合并的问题。

? ? ? ? 如果两个元素的出现区间相互重叠,则须对区间的右区间进行延长,划分为一个区间片段

? ? ? ? 我们采用贪心算法来解决这个问题,我们总是在区间的右边界上做延长,直到延长到最大可延长的位置,则划分为一个区间。

????????

1.贪心解题?

为了将其转换为区间合并问题,则:

????????首先记录每个元素的最后出现位置,与当前位置形成字母出现区间。

????????其次,根据出现区间实现区间右边界贪心探索。

????????直到右边界不能继续向右探索位置,可划分一个区间,区间数+1。

public List<Integer> partitionLabels(String s) {
        List<Integer> result=new ArrayList<>();
        //记录元素出现的最后一个位置
        int[] lastPoisition=new int[26];
        for(int i=0;i<s.length();i++){
            lastPoisition[s.charAt(i)-'a']=i;
        }
        //区间合并
        int left=0,right=lastPoisition[s.charAt(0)-'a'];
        for(int i=0;i<s.length();i++){
            //贪心右边界探索
            right=Math.max(right,lastPoisition[s.charAt(i)-'a']);
            //记录区间大小
            if(right==i){
                result.add(right-left+1);
                left=i+1;
            }
        }
        return result;
    }

2.分析

时间复杂度:O(n),时间复杂度主要用在两次遍历字符串上,n为输入字符串的长度。

空间复杂度:O(∣Σ∣),其中 Σ是字符串中的字符集。这道题中,字符串只包含小写字母,因此 ∣Σ∣=26,空间复杂度,最多划分26个区间,因为只有26个字母。

文章来源:https://blog.csdn.net/lt_BeiMo/article/details/135247535
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。