前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >763. Partition Labels

763. Partition Labels

作者头像
用户1147447
发布2019-05-26 00:38:21
3780
发布2019-05-26 00:38:21
举报
文章被收录于专栏:机器学习入门机器学习入门

LWC 67: 763. Partition Labels

Problem:

A string S of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts.

Example 1:

Input: S = “ababcbacadefegdehijhklij” Output: [9,7,8] Explanation: The partition is “ababcbaca”, “defegde”, “hijhklij”. This is a partition so that each letter appears in at most one part. A partition like “ababcbacadefegde”, “hijhklij” is incorrect, because it splits S into less parts.

Note:

  • S will have length in range [1, 500].
  • S will consist of lowercase letters (‘a’ to ‘z’) only.

思路: 很暴力,直接找可以Partition的位置,如果不能Partition,继续向后搜索直到找到第一个可以Partition的位置为止,这样剩余问题就是原问题的子问题了。

初始版本如下:

代码语言:javascript
复制
    public List<Integer> partitionLabels(String S) {
        List<Integer> ans = new ArrayList<>();
        if (S.length() == 0) return ans;

        char[] cs = S.toCharArray();
        StringBuilder sb = new StringBuilder();
        int i = 0;
        for (; i < cs.length; ++i) {
            sb.append(cs[i]);
            if (part(sb, i, S)) {
                ans.add(sb.length());
                break;
            }
        }

        List<Integer> sub = partitionLabels(S.substring(i + 1));
        for (int hello : sub) ans.add(hello);
        return ans;
    }

    public boolean part(StringBuilder sb, int i, String S) {
        if (sb.toString().isEmpty()) return false;
        for (int j = i + 1; j < S.length(); ++j) {
            String letter = S.substring(j, j + 1);
            if (sb.toString().contains(letter)) return false;
        }
        return true;
    }

再精简一点,因为调用原函数,可以在for循环中完成,所以有:

代码语言:javascript
复制
    public List<Integer> partitionLabels(String S) {
        List<Integer> ans = new ArrayList<>();
        char[] cs = S.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < cs.length; ++i) {
            sb.append(cs[i]);
            if (part(sb, i, S)) {
                ans.add(sb.length());
                sb = new StringBuilder();
            }
        }
        return ans;
    }

    public boolean part(StringBuilder sb, int i, String S) {
        if (sb.toString().isEmpty()) return false;
        for (int j = i + 1; j < S.length(); ++j) {
            String letter = S.substring(j, j + 1);
            if (sb.toString().contains(letter)) return false;
        }
        return true;
    }

万幸此答案没有超时,实际上我们还可以采用贪心的做法,降低时间复杂度。上个版本中,还需要计算StringBuilder的字符串中的每个字符是否在后续字符中出现过,实际上没有必要,我们只要记录StringBuilder中的每个字符出现的最后一个位置在哪,这样就避免每次都判断一遍,而是利用字符的最后位置直接判断。其次很重要的一点,字符串的partition的依据是:字符串中每个字符最后出现位置的整体最大值。

Java版本:

代码语言:javascript
复制
    public List<Integer> partitionLabels(String S) {
        List<Integer> ans = new ArrayList<>();
        char[] cs  = S.toCharArray();
        int n = cs.length;
        int[] last = new int[32];
        for (int i = 0; i < n; ++i) {
            last[cs[i] - 'a'] = i;
        }
        int pre = -1;
        int max = 0;
        for (int i = 0; i < n; ++i) {
            if (last[cs[i] - 'a'] > max) max = last[cs[i] - 'a'];
            if (max == i) {
                ans.add(max - pre);
                pre = max;
                max = max + 1;
            }
        }
        return ans;
    }

Python版本:

代码语言:javascript
复制
class Solution(object):
    def partitionLabels(self, S):
        """
        :type S: str
        :rtype: List[int]
        """
        lst = {}
        n = len(S)
        for i, c in enumerate(S):
            lst[c] = i
        ans = []
        max = 0
        pre = -1
        for i in range(n):
            if lst[S[i]] > max: max = lst[S[i]]
            if max == i:
                ans.append(max - pre)
                pre = max
                max = max + 1
        return ans
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年01月14日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • LWC 67: 763. Partition Labels
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档