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. PHP正则表达式基本语法

    本章主要学习正则表达式的基本语法: 正则表达式就是一个匹配的模式,正则表达式本身也就是一个字符串(有一些语法规则,特殊符号组成) 正则表达式这个字符串一定要在对应的函数中使用才有意义(分割,替换函数结 ...

  2. ORB原理与源码解析

    转载: http://blog.csdn.net/luoshixian099/article/details/48523267 CSDN-勿在浮沙筑高台 没有时间重新复制代码,只能一股脑的复制,所以代 ...

  3. 使用 mysql-proxy 监听 mysql 查询

    什么是 mysql-proxy? mysql-proxy是mysql官方提供的mysql中间件服务,上游可接入若干个mysql-client,后端可连接若干个mysql-server. 它使用mysq ...

  4. NFS服务端+客户端配置

    一.Server端配置 1.下载rpcbind和nfs #yum install -y rpcbind nfs-utils 2.创建共享文件并授权 创建共享文件夹 #mkdir /server-nfs ...

  5. Head内常用标签

    一.标签分类 1.1 自闭和标签 自闭和标签只有开头没有结尾,自动闭合: <meta> 标签 <link> 标签 1.2主动闭合标签 有开头也有结尾,是主动闭合的,称为主动闭合 ...

  6. git 使用 gitignore

    git 使用 git简介 git 命令 git  忽略文件 git   作用:版本控制 Git 是一个开源的分布式版本控制软件,用以有效.高速的处理从很小到非常大的项目版本管理. Git 最初是由Li ...

  7. NATS_03:NATS发布/订阅机制

    概念 发布/订阅(Publish/subscribe 或pub/sub)是一种消息范式,消息的发送者(发布者)不是计划发送其消息给特定的接收者(订阅者).而是发布的消息分为不同的类别,而不需要知道什么 ...

  8. Java基础-进程与线程之Thread类详解

    Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...

  9. [Java] I/O底层原理之一:字符流、字节流及其源码分析

    关于 I/O 的类可以分为四种: 关于字节的操作:InputStream 和 OutPutStream: 关于字符的操作:Writer 和 Reader: 关于磁盘的操作:File: 关于网络的操作: ...

  10. 科学计算三维可视化---TraitsUI的介绍

    TraitsUI的介绍 Python中存在Tkinter,wxPython,pyQt4等GUI图像界面编写库,这三类库要求程序员掌握众多的GUI API函数 对于科学计算的应用来说,我们希望可以快速的 ...