腾讯一面算法题:最长重复子串 1044,讲个比较好理解的思路

1044. 最长重复子串

困难

给你一个字符串 s ,考虑其所有 重复子串 :即 s 的(连续)子串,在 s 中出现 2 次或更多次。这些出现之间可能存在重叠。

返回 任意一个 可能具有最长长度的重复子串。如果 s 不含重复子串,那么答案为 “” 。

示例 1:

输入:s = “banana”
输出:“ana”

示例 2:

输入:s = “abcd”
输出:“”


题目 End…

前言

这个解法我是学习了其他大佬的题解后,我自己琢磨出的一个比较好理解的版本,但是效率并没有那么高,并且这个解法有一定误判的可能(并且官网题解也可能误判:官网使用随机数来取模 + 随机数作为进制,并且保证这两随机数的大小,所以保证了误判的概率会非常非常小,但是如果对这个随机数予以定值,仍然有可能误判,大家可以试试。个人浅见,如果有错误欢迎指出问题

所以我写的这个解法主要有两个意义:

  1. 可以以较低的成本加深大家对字符串哈希算法的理解,并且可以 完成并通过 这个题目
  2. 看了这篇文章之后,再去看官网的或者其他大佬写的更高效的版本可能会有帮助

在这里插入图片描述

思路

Version 1:暴力

首先这个是最容易想到的版本,枚举所有的子字符串,并加入哈希表中,进行判重

class Solution {
   
   
public:
    string longestDupSubstring(string s) {
   
   
        unordered_map<string, int> mp;
        string res;

        for (int i = 0; i < s.size(); i ++) {
   
   
            for (int len = 1; i + len <= s.size(); len ++) {
   
   
                string sub = s.substr(i, len);
                if (++ mp[sub] >= 2 && sub.size() > res.size()) {
   
   
                    res = sub;
                }
            }
        }

        return res;
    }
};

但是很明显会超时,第 19 个用例就无法通过。这里有几个问题可以尝试优化

  1. 是不是不需要遍历所有长度的子字符串?来优化掉这个 O ( n 2 ) O(n^2) O(n2)
  2. 在数据量非常庞大的情况下,unordered_map 可能存在性能退化的问题,在哈希冲突的情况下,时间复杂度可能会退化为 l o g 2 n log_2n log2n
  3. 其次,如果发生了哈希冲突,又需要针对哈希表红黑树结点内存值来比较 K e y Key Key 是否相等 —— 存在字符串比较,如果一个字符串长度是 3 ∗ 1 0 4 3 * 10^4 3104,那其实性能开销还是不小的

Version 2:引入二分,优化 O ( n 2 ) O(n^2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

答辣喇叭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值