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

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.

分析

看了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);
}

LeetCode828. Unique Letter String的更多相关文章

  1. [Swift]LeetCode828. 独特字符串 | Unique Letter String

    A character is unique in string S if it occurs exactly once in it. For example, in string S = " ...

  2. Unique Letter String LT828

    A character is unique in string S if it occurs exactly once in it. For example, in string S = " ...

  3. 【leetcode】828. Unique Letter String

    题目如下: A character is unique in string S if it occurs exactly once in it. For example, in string S = ...

  4. [LeetCode] 828. Unique Letter String 独特字符串

    A character is unique in string S if it occurs exactly once in it. For example, in string S = " ...

  5. ORA-00001: unique constraint (string.string) violated 违反唯一约束条件(.)

    ORA-00001: unique constraint (string.string) violated   ORA-00001: 违反唯一约束条件(.) Cause: An UPDATE or I ...

  6. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  7. leetcode array解题思路

    Array *532. K-diff Pairs in an Array 方案一:暴力搜索, N平方的时间复杂度,空间复杂度N 数组长度为10000,使用O(N平方)的解法担心TLE,不建议使用,尽管 ...

  8. All LeetCode Questions List 题目汇总

    All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...

  9. leetcode hard

    # Title Solution Acceptance Difficulty Frequency     4 Median of Two Sorted Arrays       27.2% Hard ...

随机推荐

  1. 《剑指offer》— JavaScript(16)合并两个排序的链表

    合并两个排序的链表 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. *** 思路 如果pHead1和pHead2中有一个为空,则result是另 ...

  2. @Html.DropDownListFor默认选中项

    http://q.cnblogs.com/q/73902/ 项目使用mvc4,给dropDownList指定默认值未选中 页面代码是: 1.未有默认选中值 Html.DropDownListFor(m ...

  3. opncv视频资料

    链接: http://pan.baidu.com/s/1i37nXSL 密码: 3xnd这一套opncv资料包括视频和pdf资料

  4. 在Struts2的Action中获得request response session几种方法

    转载自~ 在Struts2中,从Action中取得request,session的对象进行应用是开发中的必需步骤,那么如何从Action中取得这些对象呢?Struts2为我们提供了四种方式.分别为se ...

  5. ppp协议介绍(转)

    原文:https://www.cnblogs.com/gtarcoder/p/6259105.html PPP协议PPP协议是二层(数据链路层)协议,常用于拨号上网时客户端向服务器获取IP地址.PPP ...

  6. Python【接口开发】

    import flaskimport json #步骤一:# __name__,代表当前这个python文件server = flask.Flask(__name__) #把咱们当前这个python文 ...

  7. Kubernetes Downward API

    目录 说明 环境变量方式 将pod信息注入为环境变量 将容器资源信息注入为环境变量 volume挂载方式 作用 说明 我们知道,每个Pod在成功创建出来之后,都会被系统分配唯一的名字.IP地址,并且处 ...

  8. JVM加载一个类的过程

    类的加载过程 Java源代码被编译成class字节码,JVM把描述类数据的字节码.Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是虚拟机 ...

  9. 关于thinkpad安装win10操作系统

    thinkpad预装的是win8或者win10,会有自己的分区方式是GPT,所以会出现两个引导分区. F2进入tinkpad的bios,F12进入启动选项 我们用pe进入后,用分区工具删除两个分区,然 ...

  10. IE10下 FormsAuthentication.SetAuthCookie无效的问

    问题是这样的,我在本地测试设置身份验证票据都没问题,发布到服务器后访问地址添加了一些特殊的字符,看起来像加过密的,如下: http://www.example.com/(F(1xe9eXIxPzMAL ...