我理解的剑指offer----字符串的全排列和组合算法

信息学奥赛一本通C++语言——1199:全排列 【题目描述】 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有‘a’ <‘b’ < … <‘y’<‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。 【输入】 只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。 【输出】 输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字... 阅读详情

注:在阅读原作者的博客的基础上,我增加了一些我在阅读过程中的理解,便于大家理解,也便于我自己复习。在我自己添加的内容前我会添加【注】标记。

全排列在笔试面试中很热门,因为它难度适中,既可以考察递归实现,又能进一步考察非递归的实现,便于区分出考生的水平。所以在百度和迅雷的校园招聘以及程序员和软件设计师的考试中都考到了,因此本文对全排列作下总结帮助大家更好的学习和理解。对本文有任何补充之处,欢迎大家指出。
首先来看看题目是如何要求的(百度迅雷校招笔试题)。

一、字符串的排列

用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列,
如 abc 的全排列: abc, acb, bca, dac, cab, cba

1、全排列的递归实现

为方便起见,用123来示例下。123的全排列有123、132、213、231、312、321这六种。首先考虑213和321这二个数是如何得出的。显然这二个都是123中的1与后面两数交换得到的。然后可以将123的第二个数和每三个数交换得到132。同理可以根据213和321来得231和312。因此可以知道——全排列就是从第一个数字起每个数分别与它后面的数字交换。找到这个规律后,递归的代码就很容易写出来了:

【注】:将上面原作者描述的过程画成图就可以清晰的看出来递归的过程。

这里写图片描述

    #include<iostream>  
    using namespace std;  
    #include<assert.h>  

    void Permutation(char* pStr, char* pBegin)  
    {  
        assert(pStr && pBegin);  

        if(*pBegin == ‘\0’)  
            printf(”%s\n”,pStr);  
        else  
        {  
            for(char* pCh = pBegin; *pCh != ‘\0’; pCh++)  
            {  
                swap(*pBegin,*pCh);  
                Permutation(pStr, pBegin+1);  
                swap(*pBegin,*pCh);  
            }  
        }  
    }  

    int main(void)  
    {  
        char str[] = “abc”;  
        Permutation(str,str);  
        return 0;  
    }  

另外一种写法:

    //k表示当前选取到第几个数,m表示共有多少个数  
    void Permutation(char* pStr,int k,int m)  
    {  
        assert(pStr);  

        if(k == m)  
        {  
            static int num = 1;  //局部静态变量,用来统计全排列的个数  
            printf(”第%d个排列\t%s\n”,num++,pStr);  
        }  
        else  
        {  
            for(int i = k; i <= m; i++)  
            {  
                swap(*(pStr+k),*(pStr+i));  
                Permutation(pStr, k + 1 , m);  
                swap(*(pStr+k),*(pStr+i));  
            }  
        }  
    }  

    int main(void)  
    {  
        char str[] = “abc”;  
        Permutation(str , 0 , strlen(str)-1);  
        return 0;  
    }  

如果字符串中有重复字符的话,上面的那个方法肯定不会符合要求的,因此现在要想办法来去掉重复的数列。

2、去掉重复的全排列的递归实现

由于全排列就是从第一个数字起每个数分别与它后面的数字交换。我们先尝试加个这样的判断——如果一个数与后面的数字相同那么这二个数就不交换了。如122,第一个数与后面交换得212、221。然后122中第二数就不用与第三个数交换了,但对212,它第二个数与第三个数是不相同的,交换之后得到221。与由122中第一个数与第三个数交换所得的221重复了。所以这个方法不行。

换种思维,对122,第一个数1与第二个数2交换得到212,然后考虑第一个数1与第三个数2交换,此时由于第三个数等于第二个数,所以第一个数不再与第三个数交换。再考虑212,它的第二个数与第三个数交换可以得到解决221。此时全排列生成完毕。

【注】:将上面原作者描述的过程画成图就可以清晰的看出来递归的过程。
这里写图片描述

这样我们也得到了在全排列中去掉重复的规则——去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。下面给出完整代码:

    #include<iostream>  
    using namespace std;  
    #include<assert.h>  

    //在[nBegin,nEnd)区间中是否有字符与下标为pEnd的字符相等  
    bool IsSwap(char* pBegin , char* pEnd)  
    {  
        char *p;  
        for(p = pBegin ; p < pEnd ; p++)  
        {  
            if(*p == *pEnd)  
                return false;  
        }  
        return true;  
    }  
    void Permutation(char* pStr , char *pBegin)  
    {  
        assert(pStr);  

        if(*pBegin == ‘\0’)  
        {  
            static int num = 1;  //局部静态变量,用来统计全排列的个数  
            printf(”第%d个排列\t%s\n”,num++,pStr);  
        }  
        else  
        {  
            for(char *pCh = pBegin; *pCh != ‘\0’; pCh++)   //第pBegin个数分别与它后面的数字交换就能得到新的排列     
            {  
                if(IsSwap(pBegin , pCh))  
                {  
                    swap(*pBegin , *pCh);  
                    Permutation(pStr , pBegin + 1);  
                    swap(*pBegin , *pCh);  
                }  
            }  
        }  
    }  

    int main(void)  
    {  
        char str[] = “baa”;  
        Permutation(str , str);  
        return 0;  
    }  

OK,到现在我们已经能熟练写出递归的方法了,并且考虑了字符串中的重复数据可能引发的重复数列问题。那么如何使用非递归的方法来得到全排列了?

3、全排列的非递归实现

【注】:这种方法的前提是输入的字符串是预先由小到大排好序的

要考虑全排列的非递归实现,先来考虑如何计算字符串的下一个排列。如”1234”的下一个排列就是”1243”。只要对字符串反复求出下一个排列,全排列的也就迎刃而解了。
如何计算字符串的下一个排列了?来考虑”926520”这个字符串,我们从后向前找第一双相邻的递增数字,”20”、”52”都是非递增的,”26 “即满足要求,称前一个数字2为替换数,替换数的下标称为替换点,再从后面找一个比替换数大的最小数(这个数必然存在),(【这块没太读懂,按我自己的理解应该是,再从后往前找到第一个比替换数大的数】),0、2都不行,5可以,将5和2交换得到”956220”,然后再将替换点后的字符串”6220”颠倒即得到”950226”。
对于像“4321”这种已经是最“大”的排列,采用STL中的处理方法,将字符串整个颠倒得到最“小”的排列”1234”并返回false。

【注】:将上面原作者描述的过程画成图就可以清晰的看出来递归的过程。
这里写图片描述

这样,只要一个循环再加上计算字符串下一个排列的函数就可以轻松的实现非递归的全排列算法。按上面思路并参考STL中的实现源码,不难写成一份质量较高的代码。值得注意的是在循环前要对字符串排序下,可以自己写快速排序的代码(请参阅《白话经典算法之六 快速排序 快速搞定》),也可以直接使用VC库中的快速排序函数(请参阅《使用VC库函数中的快速排序函数》)。下面列出完整代码:

    #include<iostream>  
    #include<algorithm>  
    #include<cstring>  
    using namespace std;  
    #include<assert.h>  

    //反转区间  
    void Reverse(char* pBegin , char* pEnd)  
    {  
        while(pBegin < pEnd)  
            swap(*pBegin++ , *pEnd–);  
    }  
    //下一个排列  
    bool Next_permutation(char a[])  
    {  
        assert(a);  
        char *p , *q , *pFind;  
        char *pEnd = a + strlen(a) - 1;  
        if(a == pEnd)  
            return false;  
        p = pEnd;  
        while(p != a)  
        {  
            q = p;  
            p–;  
            if(*p < *q)  //找降序的相邻2数,前一个数即替换数    
            {  
                 //从后向前找比替换点大的第一个数  
                pFind = pEnd;  
                while(*pFind < *p)  
                    –pFind;  
                swap(*p , *pFind);  
                //替换点后的数全部反转  
                Reverse(q , pEnd);  
                return true;  
            }  
        }  
        Reverse(a , pEnd);   //如果没有下一个排列,全部反转后返回false     
        return false;  
    }  

    int cmp(const void *a,const void *b)  
    {  
        return int(*(char *)a - *(char *)b);  
    }  
    int main(void)  
    {  
        char str[] = “bac”;  
        int num = 1;  
        qsort(str , strlen(str),sizeof(char),cmp);  
        do  
        {  
            printf(”第%d个排列\t%s\n”,num++,str);   
        }while(Next_permutation(str));  
        return 0;  
    }  

至此我们已经运用了递归与非递归的方法解决了全排列问题,总结一下就是:
1、全排列就是从第一个数字起每个数分别与它后面的数字交换。
2、去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。
3、全排列的非递归就是由后向前找替换数和替换点,然后由后向前找第一个比替换数大的数与替换数交换,最后颠倒替换点后的所有数据。

二、字符串的组合

题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。
上面我们详细讨论了如何用递归的思路求字符串的排列。同样,本题也可以用递归的思路来求字符串的组合。

方法一:递归求解
假设我们想在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。针对第一个字符,我们有两种选择:第一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;第二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符。这两种选择都很容易用递归实现。下面是这种思路的参考代码:

    #include<iostream>  
    #include<vector>  
    #include<cstring>  
    using namespace std;  
    #include<assert.h>  

    void Combination(char *string ,int number,vector<char> &result);  

    void Combination(char *string)  
    {  
        assert(string != NULL);  
        vector<char> result;  
        int i , length = strlen(string);  
        for(i = 1 ; i <= length ; ++i)  
            Combination(string , i ,result);  
    }  

    void Combination(char *string ,int number , vector<char> &result)  
    {  
        assert(string != NULL);  
        if(number == 0)  
        {  
            static int num = 1;  
            printf(”第%d个组合\t”,num++);  

            vector<char>::iterator iter = result.begin();  
            for( ; iter != result.end() ; ++iter)  
                printf(”%c”,*iter);  
            printf(”\n”);  
            return ;  
        }  
        if(*string == ‘\0’)  
            return ;  
        result.push_back(*string);  
        Combination(string + 1 , number - 1 , result);  
        result.pop_back();  
        Combination(string + 1 , number , result);  
    }  

    int main(void)  
    {  
        char str[] = “abc”;  
        Combination(str);  
        return 0;  
    }  

由于组合可以是1个字符的组合,2个字符的字符……一直到n个字符的组合,因此在函数void Combination(char* string),我们需要一个for循环。另外,我们用一个vector来存放选择放进组合里的字符。

方法二:用位运算来实现求组合

    #include<iostream>  
    using namespace std;  

    int a[] = {1,3,5,4,6};  
    char str[] = “abcde”;  

    void print_subset(int n , int s)  
    {  
        printf(”{“);  
        for(int i = 0 ; i < n ; ++i)  
        {  
            if( s&(1<<i) )         // 判断s的二进制中哪些位为1,即代表取某一位  
                printf(”%c ”,str[i]);   //或者a[i]  
        }  
        printf(”}\n”);  
    }  

    void subset(int n)  
    {  
        for(int i= 0 ; i < (1<<n) ; ++i)  
        {  
            print_subset(n,i);  
        }  
    }  



    int main(void)  
    {  
        subset(5);  
        return 0;  
    }  

字符串全排列扩展—-八皇后问题

题目:在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。


这就是有名的八皇后问题。解决这个问题通常需要用递归,而递归对编程能力的要求比较高。因此有不少面试官青睐这个题目,用来考察应聘者的分析复杂问题的能力以及编程的能力。

由于八个皇后的任意两个不能处在同一行,那么这肯定是每一个皇后占据一行。于是我们可以定义一个数组ColumnIndex[8],数组中第i个数字表示位于第i行的皇后的列号。先把ColumnIndex的八个数字分别用0-7初始化,接下来我们要做的事情就是对数组ColumnIndex做全排列。由于我们是用不同的数字初始化数组中的数字,因此任意两个皇后肯定不同列。我们只需要判断得到的每一个排列对应的八个皇后是不是在同一对角斜线上,也就是数组的两个下标i和j,是不是i-j==ColumnIndex[i]-Column[j]或者j-i==ColumnIndex[i]-ColumnIndex[j]。

关于排列的详细讨论,详见上面的讲解。
接下来就是写代码了。思路想清楚之后,编码并不是很难的事情。下面是一段参考代码:

    #include<iostream>  
    using namespace std;  

    int g_number = 0;  
    void Permutation(int * , int  , int );  
    void Print(int * , int );  

    void EightQueen( )  
    {  
        const int queens = 8;  
        int ColumnIndex[queens];  
        for(int i = 0 ; i < queens ; ++i)  
            ColumnIndex[i] = i;    //初始化  
        Permutation(ColumnIndex , queens , 0);  
    }  

    bool Check(int ColumnIndex[] , int length)  
    {  
        int i,j;  
        for(i = 0 ; i < length; ++i)  
        {  
            for(j = i + 1 ; j < length; ++j)  
            {  
                if( i - j == ColumnIndex[i] - ColumnIndex[j] || j - i == ColumnIndex[i] - ColumnIndex[j])   //在正、副对角线上  
                    return false;  
            }  
        }  
        return true;  
    }  
    void Permutation(int ColumnIndex[] , int length , int index)  
    {  
        if(index == length)  
        {  
            if( Check(ColumnIndex , length) )   //检测棋盘当前的状态是否合法  
            {  
                ++g_number;  
                Print(ColumnIndex , length);  
            }  
        }  
        else  
        {  
            for(int i = index ; i < length; ++i)   //全排列  
            {  
                swap(ColumnIndex[index] , ColumnIndex[i]);  
                Permutation(ColumnIndex , length , index + 1);  
                swap(ColumnIndex[index] , ColumnIndex[i]);  
            }  
        }  
    }  

    void Print(int ColumnIndex[] , int length)  
    {  
        printf(”%d\n”,g_number);  
        for(int i = 0 ; i < length; ++i)  
            printf(”%d ”,ColumnIndex[i]);  
        printf(”\n”);  
    }  

    int main(void)  
    {  
        EightQueen();  
        return 0;  
    }  

转载:http://zhedahht.blog.163.co

题目:

输入两个整数n和m,从数列1,2,3…n中随意取几个数,使其和等于m,要求列出所有的组合。

解决方案:

    #include <iostream>  
    #include <list>  
    using namespace std;  
    list<int> list1;  
    void find_factor(int sum,int n)  
    {  
        //递归出口  
        if(n<=0||sum<=0)  
            return;  
        //输出找到的数  
        if(sum==n)  
        {  
            list1.reverse();  
            for(list<int>::iterator iter=list1.begin();iter!=list1.end();iter++)  
                cout<<*iter<<”+”;  
            cout<<n<<endl;  
            list1.reverse();  
        }  
        list1.push_front(n);  
        find_factor(sum-n,n-1);//n放在里面  
        list1.pop_front();  
        find_factor(sum,n-1);//n不放在里面  
    }  

    int main(void)  
    {  
        int sum,n;  
        cin>>sum>>n;  
        cout<<”所有可能的序列,如下:”<<endl;  
        find_factor(sum,n);  
        return 0;  
    }  
C++字符串全排列(递归法)和(迭代法)以及next_permutation底层原理详解 阅读详情

相关推荐

一本通的递归练习

递归练习 1199:全排列 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有‘a’ &amp;lt;‘b’ &amp;lt; … &amp;lt;‘y’&amp;lt;‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。 char a[10],b[10];//将a字符串的各种排列依次放到b字符串中 int vis[10],n;//用vis[i]来代表a[i]字母有没有被访问过 v...

flymist的博客 554

字符串的全排列

题目描述 输入一个字符串,打印出该字符串中字符的所有排列。 例如输入字符串abc,则输出由字符a、b、c 所能排列出来的所有字符串 abc、acb、bac、bca、cab 和 cba。 分析与解法 解法一、递归实现 从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理,从而得到所有元素的全排列。以对字符串abc进行全排列为例,我们可以这么做:以abc为例 固定...

qq_43324779的博客 5115

【算法康复训练③】剑指offer P3

文章目录 复习次数(0) 35. 包含min函数的栈 36. 字符串的排列 37. 二叉搜索树与双向链表 38. 0~n-1中缺失的数字

心海非海_のBlog 586

【算法基础】字符串的全排列算法

题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 输入描述 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。 这道题是剑指offfer中一道经典的题,如果有n个元素,我们就能有n*(n - 1)个全排列,n为1时,只有一个全排列 举...

Qregi的博客 4905

Ubuntu20.04运行Vins-fusion

因已安装ROS noetic,eigen,opencv及ceres等库,这部分环境配置就不细讲,直接下载VINS-FUSION的代码库 下载编译 cd ~/vins-fusion/src git clone https://github.com/HKUST-Aerial-Robotics/VINS-Fusion.git cd ../ catkin_make source ~/catkin_ws/devel/setup.bash 编译时会发现一堆错误,别急,无非就是环境冲突问题,一个个解决 1)首先,ROS

xiaojinger_123的博客 1万+

GB28181 2022 配置信令

基本参数视频参数选项视频参数属性配置巡航轨迹

ww506772362的专栏 1633

【吐血整理】LeetCode与剑指Offer百道经典题解总结

本文整理了LeetCode与剑指Offer中百余道经典的题目,整理出了数组、字符串、链表、二叉树、栈、回溯、动态规划、位运算中的经典问题以及问题对应的链接地址和个人提供的题解,方便查阅以及练习。以下是百题的索引,点击即可找到题目的出处并练习,也可直接查阅答案。 建议刚开始刷题的朋友直接按一下的Tag分类一个专题一个专题地进行学习与作答,完全理解这一百题,一线大厂非你莫属。

BoringError的博客 3895

云计算虚拟化实验(一)——虚拟机软件VMware的安装以及虚拟机系统的安装(Windows7+CentOS7)

主要内容: 1、虚拟机软件的安装(以VMware为例) 2、虚拟机系统的安装(Window7 + CentOS7) 3、虚拟主机网络互访 4、不同局域网内的虚拟主机互访(软路由——海蜘蛛) 0 ——首先介绍一下什么是虚拟化? 虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在

gg_asd的博客 1万+

字符串排列-全排列(C++ 剑指offer)

以下网址可以帮助大家透彻理解全排列算法: https://www.bilibili.com/video/av9830088 class Solution { public: vector<string> Permutation(string str) { //可以用递归来做 vector<string> array; ...

lr604844811的博客 2029

AI视频生成技术研究报告:现状、挑战与展望

AI 视频生成技术概述:介绍 AI 视频生成技术的基本概念,回顾其发展历程,从早期依赖图像拼接的简单生成方式,到如今融合多种先进技术的复杂模型应用,梳理技术演进的关键节点和重要突破。同时,分析该技术在当前阶段的特点,包括生成视频的质量、速度、灵活性等方面,以及与传统视频制作方式的差异,阐述 AI 视频生成技术如何改变视频创作的流程和模式。技术实现路径分析。

daqsdfas的博客 4583

visual studio 2017编译Triangle库遇到的问题和解决办法

这段时间因为一个项目需要使用到Triangle这个三角剖分工具,需要在windows环境下进行对源码编译,中间踩了很多坑,特此记录下。 1、下载 下载链接是下边这个,需要翻墙 http://www.cs.cmu.edu/~quake/triangle.html 2、编译。。超。。。级。。。麻。。。烦。。。 在ubutu下安装一切顺利,完全没遇到什么麻烦,但是换到windows下就麻烦不断...

csubai07的博客 2440

剑指Offer38:字符串的全排列

字符串的全排列 当输入a,b,c三个字符串的时候,请输出它的全部排列情况. 思路:当我们进行一个问题的解决的时候,尝试把问题分解成小问题,把一个字符串分成一个字符和n-1个字符,然后交换第一个字符和n-1个字符中的全部,然后继续固定第二个字符,继续排列n-2个字符串,这样不断继续下去,就是全排列。 思路:`List res = new ArrayList<>(); public Lis...

weixin_39137699的博客 223

【路径规划】基于matlab蚁群算法机器人栅格地图最短路径规划【含Matlab源码 4590期】

基于matlab蚁群算法机器人栅格地图最短路径规划 完整代码,包运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 1278

【剑指offer刷题】--字符串的全排列

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 解: 对122,第一个数1与第二个数2交换得到212,然后考虑第一个数1与第三个数2交换,此时由于第三个数等于第二个数,所以第一个数不再与第三个数交换。再考虑212,它的第二个数与第三个数交换可以得到解决221。此时全排...

wxq_1993的博客 243

【ComfyUI】Flux + ControlNet 边缘搭配深度、瓷砖、姿态引导图生图

本文介绍了一个基于 Wan 2.1 的 ComfyUI 文生视频工作流,通过 UNet、CLIP 和 VAE 三个核心模型,将文本提示转化为动态视频。工作流包含模型加载、提示词解析、潜空间采样等7个环节,支持分辨率、帧数等参数设置,最终输出高质量视频文件。该方案适用于创意设计、教育培训和多媒体制作等场景,能快速生成符合语义的动态内容。文章还提供了相关开发资源和学习链接,适合AI视频生成领域的研究者和实践者参考。

Mr数据杨 1634

SwiftUI 5 教程之 SwiftData使用入门(教程含源码)

对我来说,记住日期很难。是的,您可以设置该日期的提醒,但该提醒无法产生紧迫感。让我们创建一个应用程序,我们可以在其中添加将来发生的事件。如果我们可以在主应用程序上看到所有即将发生的活动,那就太好了。也许将它们添加到小部件上以营造紧迫感。对于任何事件,我们需要跟踪哪些事情?我们将在下一篇文章中添加更多属性,其中我们将讨论迁移。现在,这就是我们所需要的。开始吧。

iCloudEnd的博客 987

[剑指-Offer] 38. 字符串的排列(全排列、递归、回溯、巧妙解法)

文章目录1. 题目来源2. 题目说明3. 题目解析方法一:STL next_permutation()+巧妙解法方法二:递归+回溯+通用解法 1. 题目来源 链接:字符串的排列 来源:LeetCode——《剑指-Offer》专项 2. 题目说明 输入一个字符串,打印出该字符串中字符的所有排列。 你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。 示例: 输入:s = “abc” 输出:[...

Y-puyu 的博客 611

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

剑指Offer——字符串相关

剑指Offer——字符串相关 1、第二题 替换空格 题目描述: 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 基本思路: 首先,统计整个字符串的长度和空格的个数,在原有的基础上增加空格个数*2来放置“20”,获取到新的长度之后,从后向前遍历,依次放置新的元素。 代码实现: class ...

hei653779919的博客 226

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

剑指offer(第二版)——字符串的排列

PS:《剑指offer》是很多同学找工作都会参考的一本面试指南,同时也是一本算法指南(为什么它这么受欢迎,主要应该是其提供了一个循序渐进的优化解法,这点我觉得十分友好)。现在很多互联网的算法面试题基本上可以在这里找到影子,为了以后方便参考与回顾,现将书中例题用Java实现(第二版),欢迎各位同学一起交流进步。 GitHub: https://github.com/Uplpw/SwordOffer。 完整题目链接: https://blog.youkuaiyun.com/qq_41866626/article/detai

qq_41866626的博客 335

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

#数据结构与算法学习笔记#剑指Offer26:字符串的排列升级版 + 去重全排列问题3种解法 + 字典序算法 + 测试用例(Java、C/C++)

2018.9.3 《剑指Offer》从零单刷个人笔记整理(66题全)目录传送门​​​​​​​ 这道题比书上的题目还要复杂一些,解法总体思路差不多。花的时间比较长,因为是第一次接触全排列问题,初步实现+调试+改进花了不少时间,做完参考其他优秀的解法,又花时间进行了理解和学习,同时又从网上了解了其他很多有意思的全排列问题的解决方法,算法真是博大精深啊。题目主要复杂在哪里呢?1.字符重复,2....

NJU_ChopinXBP的博客 601

Java详解剑指offer面试题38--字符串的排列

Java详解剑指offer面试题38–字符串的排列 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 注意这道题求得是全排列。求若干字符组成的序列的所有排列可能,可以将字符序列分解成两部分: 第一个字符 第一个字符之后的字符序列 这样就把一个大问题分解成了小问题,然后对小问题继续采用相同的策略即可! 因为所有字符都可能处于第一个位置,我们可以把第一个字符和其后的所有字符交换

快乐李同学的博客 783

剑指Offer-字符串的排列

题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 输入描述: 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。 解题思路—递归:基于回溯法思想:核心思想就是固定第一个字符,递归取得首位后面的各种字符串组合;再把第一个字符与后面每一个字符交...

疯狂的兔子 1086

《剑指offer》题目 C++详细题解

如果是,则将添加到结果列表中,并返回。解题思路:这道题很有意思,核心理解是我们对于排序算法的理解,通常我们所理解的排序是比较大小的,如:升序排序的序列意思是:序列中任何一个数字,都比前面的小,比后面的大,我们把说法换一下,对于本题,我们要的有效序列是:序列中任何一个元素y,和它前的任何一个元素x进行有序组合形成xy,比和他后面的任何一个元素z进行有效序列组合yz,满足条件xy < yz(采用字典序列排序)如{32,31},有效组合是3132,所以我们拍完序列之后序列变成{31, 32}.

qq_64446981的博客 1424

【剑指offer-27】20190813/03 字符串的排列

【剑指offer-27】字符串的排列 考点:字符串 动态规划 递归 时间限制:1秒 空间限制:32768K 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 输入描述 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。 思路: 对于无重复值...

Lwolwo's 130

剑指Offer and Leetcode刷题总结之思想2:回溯算法

Leetcode46:全排序 基本思路:回溯法,track记录路线,元素之前不在track中,就append上,接着继续dfs;记住最后要pop();满了就返回return; class Solution(object): def permute(self, nums): """ :type nums: List[int] :rtype: List[List[int]] """ def dfs(nums, trac

DaBaiNiHaoBaiA的博客 527
上一篇: 最小的k个数
下一篇: 连续子数组的最大和
Findway_
博客等级 码龄10年 36粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值