ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[LeetCode] 828. Count Unique Characters of All Substrings of a Given String

2022-07-12 07:00:30  阅读:163  来源: 互联网

标签:Count index Given 子串 String int 字母 countUniqueChars 字符串


Let's define a function countUniqueChars(s) that returns the number of unique characters on s.

  • For example, calling countUniqueChars(s) if s = "LEETCODE" then "L""T""C""O""D" are the unique characters since they appear only once in s, therefore countUniqueChars(s) = 5.

Given a string s, return the sum of countUniqueChars(t) where t is a substring of s. The test cases are generated such that the answer fits in a 32-bit integer.

Notice that some substrings can be repeated so in this case you have to count the repeated ones too.

Example 1:

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

Example 2:

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

Example 3:

Input: s = "LEETCODE"
Output: 92

Constraints:

  • 1 <= s.length <= 105
  • s consists of uppercase English letters only.

统计子串中的唯一字符。

我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符,并返回唯一字符的个数。

例如:s = "LEETCODE" ,则其中 "L", "T","C","O","D" 都是唯一字符,因为它们只出现一次,所以 countUniqueChars(s) = 5 。

本题将会给你一个字符串 s ,我们需要返回 countUniqueChars(t) 的总和,其中 t 是 s 的子字符串。输入用例保证返回值为 32 位整数。

注意,某些子字符串可能是重复的,但你统计时也必须算上这些重复的子字符串(也就是说,你必须统计 s 的所有子字符串中的唯一字符)。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

首先我们看一下暴力解。对于 input 字符串,我们需要找到他所有长度不同的子串,这个时间复杂度就是O(n^2),我们还要看一下每个子串内只出现一次的字母有几个,这个复杂度是O(n),总体复杂度是O(n^3)。

这里我提供一个很巧妙的做法,我参考了这个帖子。与其去找不同子串并计算不同子串里 unique 的字母个数是多少,我们可以反过来思考,对于每个字母而言,我们可以去计算包含这个字母且这个字母只出现一次的子串有多少。只有保证当前字母只出现一次,才满足题目中 countUniqueChars() 函数的定义。

对于任意一个字母,在 input 字符串中很可能是出现了多次的。假如对于我们当前遇到的字母 X,如果我们能找到 X 在 input 字符串中上一次出现的位置 j 和下一次出现的位置 k,那么包含当前位置 i 且满足题意的子串个数应该是 (i - j) * (k - i)。

具体做法如下。我创建了一个二维数组,需要记录每个字母前两次出现位置的 index。开始遍历 input 字符串,当遇到某个字母的时候,我们把当前位置当做 k,我们去二维数组里看一下是否存在 index i 和 j,如果存在,我们就按照上面那个公式去计算一下包含当前位置上字母的子串有多少。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public int uniqueLetterString(String s) {
 3         int MOD = (int) Math.pow(10, 9) + 7;
 4         int len = s.length();
 5         int res = 0;
 6         int[][] index = new int[26][2];
 7         for (int i = 0; i < 26; i++) {
 8             Arrays.fill(index[i], -1);
 9         }
10         
11         for (int i = 0; i < len; i++) {
12             int c = s.charAt(i) - 'A';
13             res = (res + (i - index[c][1]) * (index[c][1] - index[c][0]) % MOD) % MOD;
14             index[c] = new int[] {index[c][1], i};
15         }
16         for (int c = 0; c < 26; c++) {
17             res = (res + (len - index[c][1]) * (index[c][1] - index[c][0]) % MOD) % MOD;
18         }
19         return res;
20     }
21 }

 

LeetCode 题目总结

标签:Count,index,Given,子串,String,int,字母,countUniqueChars,字符串
来源: https://www.cnblogs.com/cnoodle/p/16468617.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有