本文主要是介绍【贪心算法】Leetcode 763. 划分字母区间【中等】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
划分字母区间
- 给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。
返回一个表示每个字符串片段的长度的列表。
示例 1:
输入:s = “ababcbacadefegdehijhklij”
输出:[9,7,8]
解释:
划分结果为 “ababcbaca”、“defegde”、“hijhklij” 。
每个字母最多出现在一个片段中。
像 “ababcbacadefegde”, “hijhklij” 这样的划分是错误的,因为划分的片段数较少。
解题思路
- 1、遍历字符串s,记录每个字符最后出现的位置。
- 2、使用双指针技巧,维护一个区间[start, end],表示当前正在处理的片段。
- 3、遍历字符串s,根据当前字符的最后出现位置,不断更新end指针。
- 4、当遍历到达end位置时,表示当前片段已经结束,即后面字符没有当前片段中相同的字符。将当前片段的长度添加到结果列表中,并更新start指针为end + 1。
- 5、重复上述过程,直到遍历完整个字符串s。
Java实现
public class PartitionLabels {public List<Integer> partitionLabels(String s) {List<Integer> result = new ArrayList<>();Map<Character, Integer> lastIndexMap = new HashMap<>();// 记录每个字符最后一次出现的位置for (int i = 0; i < s.length(); i++) {lastIndexMap.put(s.charAt(i), i);}int start = 0; // 当前片段的起始位置int end = 0; // 当前片段的结束位置for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);end = Math.max(end, lastIndexMap.get(c)); // 更新当前片段的结束位置// 如果当前位置等于当前片段的结束位置// 即没有相同的字符在后面了,当前字符可以组成一个字符串了if (i == end) {result.add(end - start + 1); // 将当前片段的长度添加到结果列表中start = i + 1; // 更新当前片段的起始位置为当前位置的下一个位置}}return result;}public static void main(String[] args) {PartitionLabels solution = new PartitionLabels();String s = "ababcbacadefegdehijhklij";System.out.println("Partition labels: " + solution.partitionLabels(s)); // Output: [9, 7, 8]}
}
时间空间复杂度
-
时间复杂度:遍历字符串s,时间复杂度为O(n),其中n为字符串s的长度。
-
空间复杂度:使用了长度为26的数组lastIndex,空间复杂度为O(1)。
这篇关于【贪心算法】Leetcode 763. 划分字母区间【中等】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!