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); }
相關文章
相關標籤/搜索