Partition Labels

https://leetcode.com/problems/partition-labels/description/

题解:

题目的意思是输入一个字符串,将其尽可能地连续地分为多个字符串,且每个字符串彼此之间没有相同的字母。最后返回每个字符串的长度。由题可得,对字符串进行切分之后,相同的字母一定是属于同一字符串的。我们可以利用这个特性,先来确定并保存每个字符串的最后一个字母在原始字符串中的位置。声明now变量,用来遍历整个原始的字符串。partion变量是用来存储切分完字符串的最后一个字母的位置。

假设输入的字符串是”ababcbacadefegdehijhklij”,我们先确定切分完之后,第一个子字符串的最后一个字母的位置。由于我们不知道这个位置,所以我们先假设原始字符串的第一个字母a,是切分完第一个子字符串的最后一个字母,并把partion指向它。如果这个假设为真,则在【0,partion】的字母,不会出现在(partion,N-1】,N为原始字符串的长度。为了验证这个,我们不断的用now指向【0,partion】范围内的每个字母,来与(partion,N-1】的所有字母比较。一旦出现相同的情况,则证明目前partion的值是错误的,更新partion的值为右边相同字母的位置(字母相同则一定属于同一字符串),再继续进行验证。直到now和partion再次指向同一位置时,表明【0,partion】范围内的字母与(partion,N-1】范围内的字母没有重叠的,则确定该位置是切分完第一个子字符串的最后一个字母,将其存到list中。

当找到第一个字符串的最后一个字母的位置后,则原始字符串变为“ababcbaca”和“defegdehijhklij”。我们可以假设前面是不存在的,在“defegdehijhklij”中用同样的操作确定切分完第一个子字符串的最后一个字母的位置,存到list中。这样下去,最后能够找到所有字符串的最后一个字母的位置。然后我们把每个字符串最后一个字母的位置+1减去前一个字符串最后一个字母的位置+1(+1的操作是必须的,因为不这样做,第一个子字符串的长度会出错)。最后再返回。

class Solution {
    public List<Integer> partitionLabels(String S) {
        List<Integer> list = new ArrayList<>();
        int partion = 0, now = 0, N = S.length();
        while(now < N) {
            int i;
            for(i = partion+1; i < N; i++)
                if(S.charAt(i) == S.charAt(now)) {
                    partion = i;
                    break;
                }
            if(i == N && now==partion)
                list.add(++partion);
            now++;
        }
        for(int i = list.size()-1; i > 0; i--)
            list.set(i, list.get(i)-list.get(i-1));
        return list;
    }
}

下面是Solution里面的答案

class Solution {
    public List<Integer> partitionLabels(String S) {
        int[] last = new int[26];
        for (int i = 0; i < S.length(); ++i)
            last[S.charAt(i) - 'a'] = i;

        int j = 0, anchor = 0;
        List<Integer> ans = new ArrayList();
        for (int i = 0; i < S.length(); ++i) {
            j = Math.max(j, last[S.charAt(i) - 'a']);
            if (i == j) {
                ans.add(i - anchor + 1);
                anchor = i + 1;
            }
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值