LeetCode 763 划分字母区间

刷题日期: 2020年10月22日 00:50

题目描述

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

示例

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

提示:

S的长度在[1, 500]之间。
S只包含小写字母 ‘a’ 到 ‘z’ 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-labels
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

### 贪心

  • 一开始想用贪心的方式去解决这个问题,后来绘制出过程图发现,其分割是固定的。初次分割,必须是根据首字母对整个字符串分割成两半,分别为L_left和L_right。后续是一样的分割方式。直到最后无法分割为止。
  • 此时:从左到右,所有叶子节点对应的字符串的长度组成的List即为所求。
    初始
初始字符串L0
L_left
L_right
L_left
L_right
L_left
L_right
L_left
L_right

python 字典 / map / 哈希表

  • 因为分割是固定的。因此,只需要记录每一个字母的最左侧位置和最右侧的位置,即可完整保存分割所需要的信息。因此,第一次遍历整个字符串,保留所有字母的最左侧和最右侧的数据。若仅存在一个,则最右侧索引记为 -1.例如:

eaaaabaaec
{‘e’: 0, ‘a’: 1, ‘b’: 2, ‘c’: 3}
[0, 8], [1, 7], [5, -1], [9, -1]

  • 第二次遍历,从第一个list [left, right]开始遍历,以minIndex和 maxIndex分别表示,左侧最小值和右侧最大值。
  • 当maxIndex 小于当前List的左侧节点时,即可进行一次划分
  • 当maxIndex 为-1 时即可进行一次划分,

最终的代码

def partitionLabels(S):
    """
    :type S: str
    :rtype: List[int]
    """
    charDict = {}
    indexList = []
    for i,s in enumerate(S):
        if s in charDict.keys():
            index = charDict[s]
            indexList[index][1] = i
        else:
            charDict[s] = len(indexList)
            indexList.append([i,-1])
    result = []
    minIndex = indexList[0][0]
    maxIndex = indexList[0][1] 
    for index,i in enumerate(indexList):
        if index == 0:
            continue
        if maxIndex == -1:
            minIndex = i[0]
            maxIndex = i[1]
            result.append(1)
        elif maxIndex < i[0]:
            result.append(maxIndex - minIndex + 1)
            minIndex = i[0]
            maxIndex = i[1]
        else:
            maxIndex = max(maxIndex,i[1])  
#             print(("%s :: %s"%(minIndex,maxIndex)))

    if maxIndex == -1:
        result.append(1)
    else:
        result.append(maxIndex - minIndex + 1)
#         用于调试
#     return result,indexList,charDict
    return result

结果:

在这里插入图片描述

后续优化方向

  1. 保留尽可能少的信息;
  2. 是否可以仅遍历一次即得出结果。
  3. 使用提示信息进行结构上的优化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值