首页 > 编程知识 正文

dijkstra算法 复杂度,leetcode免费吗

时间:2023-05-05 06:20:26 阅读:136962 作者:3248

本文是《征服LeetCode》系列文章之一,该系列文章正式从2021/08/12开始。 由于LeetCode中部分主题存在摇滚,本系列至少持续到打磨所有无摇滚主题之日; 本系列的结束日期可能是永远的,因为LeetCode还在继续创建新主题。 在这篇磨练问题序列的文章中,我不仅说明了解决多道问题的思路及其优化,而且实现了用多种编程语言解题,涉及到通用解法时,我会总结出相应的算法模板。

为了在PC上运行调试并共享代码文件,还创建了相关的仓库https://github.com/memcpy0/leet code-conquest。 在这个仓库里,不仅可以看到LeetCode的原题链接、问题解决码、问题解决文章链接、同类问题的总结、通用解法的总结等,还可以看到原题的出现频率和相关企业等重要信息。 如果有其他好问题,也可以一起分享给别人。

本系列文章的内容可能随时更新、变更,因此请关注并收藏LeetCode系列的文章目录,不要忘记。

You are given a string s of length n,andanintegerk.youaretaskedtofindthe http://www.Sina.com/ktimesinstrings。

a http://www.Sina.com/isastringthatcanbederivedfromanotherstringbydeletingsomeornocharacterswithoutchangtheourorderoftheremem

asubsequenceseqis http://www.Sina.com/ktimesinthestringsifseq * kisasubsequenceofs,where seq * krepresentsastringconstructructructofs

For example,' BBA ' is repeated2timesinthestring ' babab CBA ',because the string 'bbabba ', constructedbyconcatenating ' BBA isasubsequenceofthestring ' http://www.Sina.com/a http://www.Sina.com/c 3http://ww.Sina '.return the 3358 www.return the 3358 ktimesinstrings.ifmultiplesuchsubsequencesarefound,return the 3358 ww.Sina.com/one

longest subsequence repeated

Input: s='letsleetcode ',k=2output : ' let ' explanation : therearetwolongestsubsequencesrepeated2times 3360 ' let

Input: s='bb ',k=2output : ' b ' explanation 3360 thelongestsubsequencerepeated2timesis ' b '.3358 ww.Sina

Input: s='ab ',k=2output : ' ' explanation 3360 thereisnosubsequencerepeated2times.emptystringisreturned.3358

input : s=' bbabbabbabababababababab ',k=3output : ' bbbb ' explanation 3360 thelongestsubsequence ' bbbbb ' is repeated3tid

n==s.length2=n,k=20002=NK *8sconsistsoflowercaseenglishletters .题意:给出长度为n的字符串s和整数k。 字符串s中的subsequence

重复 k 次的 最长子序列 。l

如果 seq * k 是 s 的一个子序列,其中 seq * k 表示一个由 seq 串联 k 次构造的字符串,那么就称 seq 是字符串 s 中一个 重复 k 次 的子序列。

返回字符串 s 中 重复 k 次的最长子序列  。如果存在多个满足的子序列,则返回 字典序最大 的那个。如果不存在这样的子序列,返回一个 字符串。

解法 BFS+剪枝

初一看,可能是懵的,这是个什么题啊?不过看到最后 2 <= n, k <= 2000, 2 <= n < k * 8 ,就能有点想法了。根据「鸽笼/抽屉原理」,如果有 8 个出现次数达到 k 次的字母,就达到了 8 * k ,超过了字符串 s 的长度 n 。

因此,想象长度为 m 的模式串彼此连接、重复 k 次,仍然是 s 的子序列,就很容易发现「模式串长度不超过 7」这一隐藏条件。由于小写字母只有 26 个,我们枚举长度 [1, 7] 的模式串——或者说由长度为 1 的模式串逐步BFS,每次对当前模式串添加一个新字母得到新模式串 t ,如果在字符串 s 中找不到 k 个及以上的 t 时,就不要尝试在 t 后面添加新字母了(剪枝策略),否则将 t 入队。如此不断操作,直到队列为空。

一个小小的疑问是,为什么明明是重复 k 次的最长子序列,却可以重复更多次呢?很简单,仔细看题意——如果 seq * k 是 s 的子序列,且 seq * k 表示由 seq 串联 k 次构造的字符串,则 seq 就是 s 中一个重复 k 次的子序列。显而易见,seq 如果在 s 中重复了 k 次以上,那么 seq * k 也必然是 s 的子序列。

实际代码如下所示。整个算法的理论时间复杂度为 O ( 2 4 7 ∗ n ∗ m ) O(24^7 * n * m) O(247∗n∗m) ,不过由于剪枝的使用,实际效率高得多。

//C++ versionclass Solution {private: int checkCount(const string &sub, const string &s) { int n = sub.size(), m = s.size(), i = 0, j = 0, cnt = 0; while (j < m) { if (sub[i] == s[j]) { ++i; if (i == n) ++cnt, i = 0; } ++j; } return cnt; }public: string longestSubsequenceRepeatedK(string s, int k) { int n = s.size(); if (n < k) return ""; //n个字符不足以让一个子序列重复k次 queue<string> q; q.push(""); string ans; while (!q.empty()) { string p = q.front(); q.pop(); ans = p; //p是更长的、字典序更大的,重复k次的子序列 for (char c = 'a'; c <= 'z'; ++c) { //从a加到z,保证队列中的数据一定按照字典序、且长度非递减排列 string t = p + c; if (checkCount(t, s) >= k) q.push(t); } } return ans; }};//执行用时:584 ms, 在所有 C++ 提交中击败了40.63% 的用户//内存消耗:8 MB, 在所有 C++ 提交中击败了70.76% 的用户

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。