[M贪心] lc763. 划分字母区间(贪心+代码实现)

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[M贪心] lc763. 划分字母区间(贪心+代码实现)相关的知识,希望对你有一定的参考价值。

文章目录

1. 题目来源

链接:763. 划分字母区间

2. 题目解析

lc 讨论中看见的华为 od 面试编程题目,可以试试。

贪心思路:

  • 本次分割字符串如果在后面都不出现,则单独成一段,作为有效答案。因为这样分割一定不会使答案变差。贪心思路正确。
  • 维护每个字符最后出现的位置下标,从前到后遍历字符串,统计当前遍历字符串中所出现字符的最大下标值,若当前下标等于最大下标,说明已遍历的字符串中的所有字符在后续不会再次出现,则可以作为答案,计算长度即可。

坐在高铁上简单写了写,代码不够简洁。以下几点需要注意:

  • 维护字符最后出现的位置
    • 可以从后向前遍历,记录第一次出现时的下标值即可
    • 可以从前向后遍历,遇见字符即记录下标,覆盖式记录,代码优雅
  • 采用双指针 l, r 来维护目标区间,不用统计长度,代码更加简洁
    • 右区间 r 维护当前字符串的最大下标位置,l 维护起始位置
    • 一定会有答案,整段为答案,当前下标与最大下标位置相等时则找到一个答案。计算长度为 r-l+1,更新左区间起点 lr 的下一个位置。r 不需要更新,下一个字符位置一定大于当前的 r

  • 时间复杂度 O ( n ) O(n) O(n)
  • 空间复杂度 O ( 1 ) O(1) O(1)

class Solution 
public:
    vector<int> partitionLabels(string s) 
        int n = s.size();
        vector<int> arr(26, -1);
        for (int i = n - 1; ~i; i -- ) 
            if (arr[s[i] - 'a'] == -1) arr[s[i] - 'a'] = i;
        

        vector<int> res;
        int midx = -1, cur = 0;
        for (int i = 0; i < n; i ++ ) 
            cur ++ ;
            midx = max(arr[s[i] - 'a'], midx);
            if (i == midx) 
                res.push_back(cur);
                midx = -1;
                cur = 0;
                continue;
            
        

        return res;
    
;

较为优雅的代码实现:

class Solution 
public:
    vector<int> partitionLabels(string S) 
        int n = S.size();
        int hash[26] = 0;
        for (int i = 0; i < n; ++i) hash[S[i] - 'a'] = i;
        
        vector<int> res;
        int l = 0, r = 0;
        for (int i = 0; i < n; ++i) 
            r = max(r, hash[S[i] - 'a']);
            if (i == r) res.push_back(r - l + 1), l = r + 1;
        
        return res;
    
;

以上是关于[M贪心] lc763. 划分字母区间(贪心+代码实现)的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 763. 划分字母区间贪心策略:局部最优大区间划分

763. 划分字母区间-贪心算法

leetcode 763. 划分字母区间贪心策略:局部最优大区间划分

leetcode 763. 划分字母区间贪心策略:局部最优大区间划分

leetcode 763. 划分字母区间贪心策略:局部最优大区间划分

贪心算法:划分字母区间