• LeetCode·每日一题·828.统计子串中的唯一字符·数学


    链接:https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/solution/by-xun-ge-v-a7p1/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 

    题目

     

    示例

     

    思路

    解题思路
    【动态规划】

    定义sum为以当前字符结尾的字符串的唯一字符之和。

    当遍历到第k个字符时,有三种情况:

    • 字符尚未出现过,则所有以该字符结尾的字符串的唯一字符个数为sum+k。
    • 字符出现过一次,上一次出现位置为a,那么前a个字符开始的字符串提供的唯一字符个数需要减少a,后k-a个字符开始的字符串的提供的唯一字符个数需要累加k-a,则所有以该字符结尾的串的唯一字符个数为 sum+k-2a。
    • 字符出现过多次,上一次出现位置为a,上上次出现位置为b,那么以前b个字符开始的字符串的提供的唯一字符个数不变,而中间a-b个字符开始的字符串提供的唯一字符个数需要减少a-b,后k-a个字符开始的字符串提供的唯一字符个数需要累加k-a,所有以该字符结尾的串的唯一字符个数为 sum+k-2a+b。

    代码

    【数学思维】

    1. /*
    2. MOST_CHARS: 共26个大写字母。
    3. INIT_POSITION: 假想字符串最左端,即下标-1处有一个虚拟的相同字符。
    4. x: 循环下标。
    5. length: 字符串长度。
    6. ch: 字母表中的顺序,A对应0,B对应1,C对应2,……,Z对应25。
    7. result: 结果值。题目保证不会越界int类型。
    8. near[26]: 每个字符左侧离它最近的下标位置。
    9. farther[26]: 每个字符左侧离它第二近的下标位置。
    10. */
    11. #define MOST_CHARS 26
    12. #define INIT_POSITION -1
    13. int uniqueLetterString(char *s)
    14. {
    15. int x = 0, length = 0, ch = 0, result = 0;
    16. int farther[MOST_CHARS], near[MOST_CHARS];
    17. /* 初始化为-1。 */
    18. memset(farther, INIT_POSITION, sizeof(farther));
    19. memset(near, INIT_POSITION, sizeof(near));
    20. /* 遍历一趟字符串。 */
    21. while('\0' != s[x])
    22. {
    23. /* 当前字符在字母表中的顺序。 */
    24. ch = s[x] - 'A';
    25. /* 如果near[ch]不等于-1,表示非第一次出现,此时,它左侧的那个相同字符即可计算其贡献值了。 */
    26. if(INIT_POSITION != near[ch])
    27. {
    28. result += (x - near[ch]) * (near[ch] - farther[ch]);
    29. }
    30. /* 更新near和farther。 */
    31. farther[ch] = near[ch];
    32. near[ch] = x;
    33. x++;
    34. }
    35. /* 字符串遍历到结束符时,x值就等于字符串长度length。 */
    36. length = x;
    37. /* 最后一个字符的贡献值。 */
    38. x = 0;
    39. while(MOST_CHARS > x)
    40. {
    41. /* 不等于-1时,才说明这个字符是存在过的。
    42. 等于-1的话,则表示这个字符在字符串中从头到尾没有出现过。 */
    43. if(INIT_POSITION != near[x])
    44. {
    45. result += (length - near[x]) * (near[x] - farther[x]);
    46. }
    47. x++;
    48. }
    49. return result;
    50. }
    51. 作者:xun-ge-v
    52. 链接:https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/solution/by-xun-ge-v-a7p1/
    53. 来源:力扣(LeetCode)
    54. 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    【动态规划】

    1. #define MOD 1000000007
    2. int uniqueLetterString(char *str) {
    3. int at1[26] = { 0 }, at2[26] = { 0 }, sum = 0, ans = 0;
    4. for (int i = 0; str[i]; ++i) {
    5. int pos = str[i] - 'A';
    6. sum += i + 1 - 2 * at1[pos] + at2[pos];
    7. ans += sum, ans %= MOD;
    8. at2[pos] = at1[pos], at1[pos] = i + 1;
    9. }
    10. return ans;
    11. }
    12. 作者:xun-ge-v
    13. 链接:https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/solution/by-xun-ge-v-a7p1/
    14. 来源:力扣(LeetCode)
    15. 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    内网渗透之内网信息收集(五)
    Java安全—CommonsCollections4
    Fedora或CentOS运行dnf update报错
    网络安全-抓包和IP包头分析
    【MyBatis】MyBatis是什么?能干什么?一篇学习MyBatis,知识点详细解释,实例演示
    npm run serve与npm run dev的区别
    c++标准模板库:STL
    如何把照片转成pdf文件,支持合并转换
    C++11:右值引用
    冷链监测之稳定性预算
  • 原文地址:https://blog.csdn.net/m0_64560763/article/details/126720775