回溯算法+DFS初探,字符串全排序问题浅度分析

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出
来的所有字符串 abc,acb,bac,bca,cab 和 cba
 

观察字符串

abc acb bac cab cba

可以发现是

有3个字母,分别以每一个字母做为第一个,然后再以不是这个字母的剩下两个字母作为子问题的第一个得到的解。

也就是说,我们把这个问题转换成选一个没有重复的字母做为第一个,然后缩小区间,把剩下两个字母当作是一个全新的问题,不断循环直到问题解决

那么我们要解决的问题就是:选择一个字母放到第一个的位置。子问题是再选择一个不重复的字母放到子问题的第一个位置。以此类推。

这里实际上体现了一个思想:就是我们把字符串的问题转换成了用一颗多叉树解决的问题

先看一下代码吧

class Solution{
public:
     void Swap(string&str, int i, int j)
     {
         char temp = str[i];
         str[i] = str[j];
         str[j] = temp;
     }
     
     bool isEx(string&str, vector<string>&result)
     {
         for(auto it = result.begin(); it != result.end(); it++)
         {
             if(str == *it)
             {
                 return true;
             }
         }
         return false;
     }
     void PermutationHelper(string&str, vector<string>&result, int start)
     {
         if(start == str.size())
         {
             if(!isEx(str,result)
             {
                 result.push_back(str);
             }
         }
         for(int i = start; i < str.size(); ++i)//这里的i是为了让问题的其实进行不断的变化
         {
             swap(str, start, i)
             PermutationHelper(str, result, start + 1);//这里是为了把问题不断拆分成子问题
             swap(str, start, i)
         }
     }
     vector<string> Permutation(string&str)
     {
         vector<string> result;
         if(str.size() > 0)
         {
             PermutationHelper(str, result, 0);
         }
         return result;
     } 

 先了解哪里用了回溯算法了?

答案是递归过后的swap这里是一个回溯的过程,我们可以想象一下,我们为什么要使用这个for循环,for循环是为了宽度,递归是深度遍历,是为了深度。我们如果把这个字符串当作成为一棵多叉树的话,那么这个递归就是DFS深度优先遍历。如果这棵树是二叉树的话,那么递归方式就是root->left和root->right递归就可以了。但是正因为这是一颗多叉树,所以我们不可以这样遍历,多叉树的遍历方式应该是通过某种媒介让一枝变成多枝。没有循环就是一枝不断深入,循环可以让其变成多枝。

没有循环的话那么从头到尾都将是一枝。 所以循环的作用是让子问题分叉。

循环让树变宽,递归让其变深。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

胡桃姓胡,蝴蝶也姓胡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值