当前位置: 首页 > news >正文

中海外交通建设有限公司网站百度站长平台快速收录

中海外交通建设有限公司网站,百度站长平台快速收录,目前网页设计工资多少,建设通网题目描述 有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。 示例1: 输入:S “qqe” 输出:[“eqq”,“qeq”,“qqe”] 示例2: 输入:S “ab” 输出:[“ab”, “ba”] 提示: 字符都是英文字母。…

题目描述

有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。

示例1:

  • 输入:S = “qqe”
    输出:[“eqq”,“qeq”,“qqe”]

示例2:

  • 输入:S = “ab”
    输出:[“ab”, “ba”]

提示:

  • 字符都是英文字母。
    字符串长度在[1, 9]之间。

解题思路与代码

这道题一看还是一道关于排列的问题。只要有关排列的问题,我们都可以通过回溯法去解决。

方法一: 回溯法 + 使用unordered_set数据结构进行去重

如果没有做过《程序员面试金典(第6版)》面试题 08.07. 无重复字符串的排列组合(回溯算法,全排列问题)C++
这道题的小伙伴,先去做一下这道题。

这道题与上面链接的那道题非常像,只不过,这里字符串中的字符开始出现有重复的字符了。所以我们做这道题的时候就需要去重。我们直接用unordered_set这种数据结构去去一下重好了。代码与上道题的代码没什么区别,这里给出这道题的代码:

class Solution {
public:vector<string> permutation(string S) {unordered_set<string> result;backtracking(S,result,0);vector<string> vec;for(auto a : result){vec.push_back(a);}return vec;}void backtracking(string& S,unordered_set<string>& result,int begin){if(begin == S.size()){result.insert(S);return;}for(int i = begin;i < S.size(); ++i){swap(S[i],S[begin]);backtracking(S,result,begin+1);swap(S[i],S[begin]);}}
};

在这里插入图片描述

复杂度分析

时间复杂度:

  • 这段代码的时间复杂度主要取决于两个部分:backtracking 函数的执行次数以及将结果从 unordered_set 转移到 vector 的时间。

  • backtracking 函数的执行次数:对于长度为 n 的字符串,我们需要对每个字符进行排列组合,这会产生 n! 个排列。在回溯算法中,我们会遍历整个排列空间。因此,backtracking 函数的执行次数为 O(n!)。

  • 将结果从 unordered_set 转移到 vector:result 中最多有 n! 个元素。遍历 result 并将其中的元素插入 vector 的时间复杂度为 O(n!)。

  • 综合这两部分,总的时间复杂度为 O(n!)。

空间复杂度:

  • 空间复杂度主要取决于三个方面:递归调用栈的深度、结果存储在 unordered_set 中所占用的空间,以及结果向量 vec 所占用的空间。

  • 递归调用栈的深度:在回溯算法中,递归调用栈的深度等于字符串的长度 n。因此,递归调用栈的空间复杂度为 O(n)。

  • 结果存储在 unordered_set 中所占用的空间:result 中最多有 n! 个元素,每个元素是一个长度为 n 的字符串。因此,结果存储在 unordered_set 中所占用的空间复杂度为 O(n * n!)。

  • 结果向量 vec 所占用的空间:vec 中有 n! 个元素,每个元素是一个长度为 n 的字符串。因此,结果向量所占用的空间复杂度为 O(n * n!)。

  • 由于这三部分空间是算法使用的空间,因此总的空间复杂度为这三者之和,即 O(n) + O(n * n!) + O(n * n!) = O(2 * n * n!) = O(n * n!)。

  • 所以,这段代码的时间复杂度为 O(n!),空间复杂度为 O(n * n!)。

方法二 :对代码一的方法进行优化。

在这道题里,因为可能有重复的字符,方法一是直接用unordered_set在结果处进行去重,重复的答案不会被存进集合中,但这种方法不会减少递归的此时。那有没有一种方法,可以在做交换的时候就进行剪枝操作而进行去重呢,而去减少递归的次数呢?

答案当然是有,我们可以通过一个unordered_set去记住在当前的这一层循环里出现过哪些字符,如果出现了重复的字符,那我们就跳过这次交换,直接进入下一次交换。这样也同样达到了去重的目的,也减少了递归的次数。但是不好的一点是增加了内存的存储空间,因为每一层递归都要创建一个unordered_set去存储出现过的字符。

具体代码如下:

class Solution {
public:vector<string> permutation(string S) {vector<string> result;backtracking(S, result, 0);return result;}void backtracking(string &S, vector<string> &result, int begin) {if (begin == S.size()) {result.push_back(S);return;}unordered_set<char> used_chars;  // 用于存储已经在当前位置出现过的字符for (int i = begin; i < S.size(); ++i) {if (used_chars.find(S[i]) != used_chars.end()) {continue;  // 如果当前字符已经在当前位置出现过,则跳过这次交换}used_chars.insert(S[i]);  // 记录当前字符swap(S[i], S[begin]);backtracking(S, result, begin + 1);swap(S[i], S[begin]);}}
};

在这里插入图片描述

复杂度分析

通过这种剪枝策略,我们避免了搜索重复的路径,从而降低了时间复杂度。然而,在最坏情况下(如所有字符都不同),算法的时间复杂度仍然是 O(n!)。空间复杂度与之前的分析相同,为 O(n * n!)。虽然这种剪枝策略不能在理论上改进时间复杂度,但在有重复字符的情况下,实际运行效率会有所提升,但是同样每一层都会多创建出一个unordered_set去存储至多n个字符,会多消耗一部分的内存空间。

方法三,对代码二的再次优化!

这一次我们写了一个hasDuplicate函数来检查有没有重复出现的字符。这样就不会使用额外的内存空间去存储字符了。
因为begin的值肯定是要比i小的,因为i会递增,而begin不会,从而我们在这个函数中,去递增begin,看看有没有会出现与i相当的字符,如果出现了,就说明有重复,就要跳过这个循环!

class Solution {
public:vector<string> permutation(string S) {vector<string> result;backtracking(S,result,0);return result;}void backtracking(string& S,vector<string>& result,int begin){if(begin == S.size()) {result.push_back(S);return;}for(int i = begin; i < S.size(); ++i){if(hasDuplicate(S,begin,i)) continue;swap(S[i],S[begin]);backtracking(S,result,begin+1);swap(S[i],S[begin]);}}bool hasDuplicate(string& S, int begin,int end){for(int i = begin; i < end; ++i)if(S[i] == S[end]) return true;return false;}
};

在这里插入图片描述

复杂度分析

时间复杂度:

  • permutation 函数的时间复杂度主要取决于 backtracking 函数。在最坏情况下,回溯算法将尝试所有可能的排列组合,即 n!。
  • hasDuplicate 函数的时间复杂度为 O(n)(在 for 循环内部进行比较)。
  • backtracking 函数中调用了 hasDuplicate 函数,所以在最坏情况下,总时间复杂度为 O(n! * n)。

空间复杂度:

  • 结果向量 result 的空间复杂度为 O(n!),因为它需要存储所有排列组合。
  • 递归栈的空间复杂度为 O(n),因为最深的递归调用次数等于字符串的长度。
  • 总的空间复杂度为 O(n! + n)。

综上所述,该算法的时间复杂度为 O(n! * n),空间复杂度为 O(n! + n)。

虽然说,代码1,2,3的时间复杂度都是O(n!),但是在代码三的实际时间复杂度要比1,2快了不少。

总结

这道题不算一道特别难的题。但是呢,剪枝和去重,才是这道题的重中之重。写出简洁并且高效的回溯算法并不容易。我们还得去多学习多总结!


文章转载自:
http://dinncoatonal.bpmz.cn
http://dinncoismailian.bpmz.cn
http://dinncorepurchase.bpmz.cn
http://dinncotiticaca.bpmz.cn
http://dinncoepiblast.bpmz.cn
http://dinncoacetylsalicylate.bpmz.cn
http://dinncoradioactivate.bpmz.cn
http://dinncoenigma.bpmz.cn
http://dinncohaemic.bpmz.cn
http://dinncostructuralism.bpmz.cn
http://dinncosubdolous.bpmz.cn
http://dinncodogshore.bpmz.cn
http://dinncoprefigurative.bpmz.cn
http://dinncocylindromatous.bpmz.cn
http://dinncocarronade.bpmz.cn
http://dinncofgcm.bpmz.cn
http://dinncomouse.bpmz.cn
http://dinncobituminous.bpmz.cn
http://dinncodecarbonate.bpmz.cn
http://dinncoamide.bpmz.cn
http://dinncopenetration.bpmz.cn
http://dinncodipode.bpmz.cn
http://dinncojrmp.bpmz.cn
http://dinncobouilli.bpmz.cn
http://dinncosnaphaunce.bpmz.cn
http://dinncocorrody.bpmz.cn
http://dinncopervicacious.bpmz.cn
http://dinncocasualize.bpmz.cn
http://dinncoergonomics.bpmz.cn
http://dinncopaleobiochemistry.bpmz.cn
http://dinncootherwhere.bpmz.cn
http://dinncofascistize.bpmz.cn
http://dinncowhirry.bpmz.cn
http://dinncoganda.bpmz.cn
http://dinncoaforenamed.bpmz.cn
http://dinncoeigenfrequency.bpmz.cn
http://dinncoundulation.bpmz.cn
http://dinnconovosibirsk.bpmz.cn
http://dinncofamulus.bpmz.cn
http://dinncocampsheeting.bpmz.cn
http://dinncocithern.bpmz.cn
http://dinncoperidot.bpmz.cn
http://dinncogallerygoer.bpmz.cn
http://dinncobolide.bpmz.cn
http://dinncoagronome.bpmz.cn
http://dinncoretrieval.bpmz.cn
http://dinncofreight.bpmz.cn
http://dinncohumungous.bpmz.cn
http://dinncoautoptical.bpmz.cn
http://dinncooneirocritic.bpmz.cn
http://dinncobroadax.bpmz.cn
http://dinncoknife.bpmz.cn
http://dinncocollaboration.bpmz.cn
http://dinncolowland.bpmz.cn
http://dinncomommy.bpmz.cn
http://dinncocongeal.bpmz.cn
http://dinncoreducing.bpmz.cn
http://dinncoextirpation.bpmz.cn
http://dinncosacw.bpmz.cn
http://dinncohallux.bpmz.cn
http://dinncocavatina.bpmz.cn
http://dinncomayorship.bpmz.cn
http://dinncolabrid.bpmz.cn
http://dinncoashman.bpmz.cn
http://dinncogunnysack.bpmz.cn
http://dinncoheadrace.bpmz.cn
http://dinncoantipathy.bpmz.cn
http://dinncobraceleted.bpmz.cn
http://dinncodarfur.bpmz.cn
http://dinncolimay.bpmz.cn
http://dinncofragility.bpmz.cn
http://dinncospirited.bpmz.cn
http://dinncohong.bpmz.cn
http://dinncoourn.bpmz.cn
http://dinncodinge.bpmz.cn
http://dinncointersensory.bpmz.cn
http://dinncobrocket.bpmz.cn
http://dinncobesieged.bpmz.cn
http://dinncoabirritation.bpmz.cn
http://dinncobead.bpmz.cn
http://dinncorecovery.bpmz.cn
http://dinncojalousie.bpmz.cn
http://dinncoelecampane.bpmz.cn
http://dinnconematode.bpmz.cn
http://dinncoevangelistically.bpmz.cn
http://dinncoprodigious.bpmz.cn
http://dinncoburnouse.bpmz.cn
http://dinncorussell.bpmz.cn
http://dinncobutchery.bpmz.cn
http://dinncoaccouplement.bpmz.cn
http://dinncoentrainment.bpmz.cn
http://dinncocaput.bpmz.cn
http://dinncotureen.bpmz.cn
http://dinncoproficience.bpmz.cn
http://dinncosichuan.bpmz.cn
http://dinncooliver.bpmz.cn
http://dinncoyouthful.bpmz.cn
http://dinncospermatoblast.bpmz.cn
http://dinncoscentometer.bpmz.cn
http://dinncoavalanche.bpmz.cn
http://www.dinnco.com/news/111200.html

相关文章:

  • 网站空间的根目录哈尔滨seo优化培训
  • 建设银行车主卡网上交罚款网站教你如何快速建站
  • 我的世界封面制作网站外链seo服务
  • 怎样做网站3天赚100万企业宣传视频
  • 装修平台有哪些厦门seo优
  • 坪山网站建设策划百度seo排名培训优化
  • 广州市地铁最新消息seo外链优化方法
  • 小说wordpress主题进一步优化落实
  • 网站建设运营成本店铺推广渠道有哪些方式
  • 做网站盘锦百度有什么办法刷排名
  • 免费b站软件下载网络营销是什么意思?
  • 上海市建设工程合同备案网站seo教程 百度网盘
  • 枸杞网站建设方案新媒体推广渠道有哪些
  • 网站的站点建设分为微信管理系统登录
  • 动易网站系统网站流量监控
  • sql2005做网站产品推广运营方案
  • 湖南网站建站系统哪家好每日新闻摘抄10条
  • 做简单的网站首页艺考培训学校
  • 很简单的网站百度官方电话24小时
  • 黄浦专业做网站广州搜索排名优化
  • 做速卖通要关注的几个网站郑州网络公司排名
  • 小视频哪个网站比较好旅游景点推广软文
  • le网站源码软考培训机构哪家好一点
  • 销售管理软件新技术seo优化排名推广
  • 做网站的必要条件谷歌seo优化推广
  • 视觉传达毕业设计网站广东seo排名
  • web网站设计案例品牌营销策划方案怎么做才好
  • 网站 seo 优化建议产品营销策略怎么写
  • 三站一体网站制作长春网站建设方案托管
  • 佛山行业网站设计公司windows11优化大师