1. 程式人生 > >【leetcode】828. Unique Letter String

【leetcode】828. Unique Letter String

ons 表示 letter int strong ise style xpl self

題目如下:

A character is unique in string S if it occurs exactly once in it.

For example, in string S = "LETTER", the only unique characters are "L" and "R".

Let‘s define UNIQ(S) as the number of unique characters in string S.

For example, UNIQ("LETTER") = 2.

Given a string S with only uppercases, calculate the sum of UNIQ(substring)

over all non-empty substrings of S.

If there are two or more equal substrings at different positions in S, we consider them different.

Since the answer can be very large, return the answer modulo 10 ^ 9 + 7.

Example 1:

Input: "ABC"
Output: 10
Explanation: All possible substrings are: "A","B","C","AB","BC" and "ABC".
Evey substring is composed with only unique letters.
Sum of lengths of all substring is 1 + 1 + 1 + 2 + 2 + 3 = 10

Example 2:

Input: "ABA"
Output: 8
Explanation: The same as example 1, except uni("ABA") = 1.

Note: 0 <= S.length <= 10000.

解題思路:在任何子串中,只有出現一次的字符才對最終的結果起作用。假設輸入的S為 XXXAXXXXAXXAXXXXX,X表示其他任意字符,現在我們來計算藍A對最後的輸出貢獻了多少,很顯然在兩個紅A之間的子串中,只要是包括藍A的子串都有藍A的貢獻,如果第一個紅A到藍A之間的字符數量是L,藍A到第二個紅A之間的字符數量是R,那麽藍A的貢獻就是 L + R + L*R + 1 ,其中L表示藍A與左邊字符組成的子串數量,R為與右邊的,L*R為同時與左右結合,1表示不與任何字符結合。所有只有找出所有字符左右兩邊相同字符出現的位置,即可計算出最終的答案。

代碼如下:

class Solution(object):
    def uniqueLetterString(self, S):
        """
        :type S: str
        :rtype: int
        """
        dic = {}
        for i,v in enumerate(S):
            dic[v] = dic.setdefault(v,[]) + [i]

        res = 0
        import bisect
        for i,v in enumerate(S):
            inx = bisect.bisect_left(dic[v], i)
            before = i
            after = len(S) - i - 1
            if inx - 1 >= 0:
                before = i - dic[v][inx - 1] - 1
            if inx + 1 < len(dic[v]):
                after = dic[v][inx + 1] - i - 1
            res += (before + after + before * after + 1)
        return res % (pow(10, 9) + 7)

【leetcode】828. Unique Letter String