LeetCode828. Unique Letter String

https://leetcode.com/problems/unique-letter-string/description/app

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

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

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

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

Given a string S with only uppercases, calculate the sum of UNIQ(substring) over all non-empty substrings of S.code

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

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

Example 1:leetcode

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.

分析

看了discuss,大神的思惟和我等常人就是不同,跪服。首先以字符串XAXAXXAX为例,若是将第二个 A 变成惟一的character的话,只可能时某个惟一的substring包含了这个A。好比:

We can take "XA(XAXX)AX" and between "()" is our substring.

利用这种方式,能够使得第二个A成为惟一的character,那么从上可知咱们要作的是:

We can see here, to make the second "A" counted as a uniq character, we need to:

  1. insert "(" somewhere between the first and second A
  2. insert ")" somewhere between the second and third A

For step 1 we have "A(XA" and "AX(A", 2 possibility.
For step 2 we have "A)XXA""AX)XA" and "AXX)A", 3 possibilities.

So there are in total 2 * 3 = 6 ways to make the second A a unique character in a substring.
In other words, there are only 6 substring, in which this A contribute 1 point as unique string.

如今逆转下思惟,一开始的思惟是在原字符串的全部子串中寻找可能的惟一的character,咱们如今就直接在S中来计算每一个字符,看看对于每一个unique char总公有多少种不一样的找法。换而言之就是,对于S中的每一个字符,若是他做为unique char的话,那么包含他的substring的范围是在前一个相同字符以及后一个相同字符这个区间内找的(参见上面的A),将全部可能的substring数量加起来便可,颇有趣的逆向思惟。

Explanation:

  1. index[26][2] record last two occurrence index for every upper characters.
  2. Initialise all values in index to -1.
  3. Loop on string S, for every character c, update its last two occurrence index to index[c].
  4. Count when loop. For example, if "A" appears twice at index 3, 6, 9 seperately, we need to count:
    • For the first "A": (6-3) * (3-(-1))"
    • For the second "A": (9-6) * (6-3)"
    • For the third "A": (N-9) * (9-6)"

代码

  public int uniqueLetterString(String S) { int[][] index = new int[26][2]; for (int i = 0; i < 26; ++i) Arrays.fill(index[i], -1); long res = 0, N = S.length(), mod = (int) Math.pow(10, 9) + 7; for (int i = 0; i < N; i++) { int c = S.charAt(i) - 'A'; res = res + (i - index[c][1]) * (index[c][1] - index[c][0]); index[c] = new int[]{index[c][1], i}; }
  // 计算最后的c
for (int c = 0; c < 26; ++c) res = res + (N - index[c][1]) * (index[c][1] - index[c][0]); return (int) (res % mod); }
相关文章
相关标签/搜索