字符串全排列与组合算法以及八皇后问题
【剑指offer-题38】
字符串排列
题目
输入一个字符串,输出该字符串的全排列。
思路
数学中的排列思想。算法步骤如下:
- 求出所有可能出现在第一个位置的字符。将首字符依次与后面的字符交换,即可达到此目的。
- 确定完第一个位置的字符之后,后面的字符作为一个新的字符串,求其全排列,也就是递归算法。
- 将某个字符与首字符交换,求解完它的所有全排列之后,需要将首字符放回原位,方便首字符与后面字符继续交换。
实现代码
void SwitchToFront(char* pStr, char* pPos)
{char chTemp = *pPos;*pPos = *pStr;*pStr = chTemp;
}//pStr - 待求取全排列的字符串
//pStart - 当前递归的首字符位置
void PermutationReversely(char* pStr, char* pStart)
{if (*(pStart + 1) == '\0'){cout << pStr << endl;}else{for (char *pCh = pStart; *pCh != '\0'; pCh++){//将首字符与其后字符交换SwitchToFront(pStart, pCh);//增加首字符指针,递归遍历后面的字符串PermutationReversely(pStr, pStart + 1);//将首字符回归原位,为后续字符交换做准备SwitchToFront(pStart, pCh);}}
}//主函数
void Permutation(char* pStr)
{if (!pStr || *pStr == '\0')return;PermutationReversely(pStr, pStr);
}
这里会有一个问题,如果字符串中有相同的字符时,会出现相同的排列。所以,应该先检查当前待交换字符之前是否已经出现过,如果出现过,则不进行任何处理,直接处理下一个字符。
修改后的代码
//判断当前字符是否已经出现过
bool CheckIfExist(char* pStr, const char* pCh)
{char* p = pStr;while (p != pCh){if (*p == *pCh)return true;p++;}return false;
}//pStr - 待求取全排列的字符串
//pStart - 当前递归的首字符位置
void PermutationReversely(char* pStr, char* pStart)
{if (*(pStart + 1) == '\0'){cout << pStr << endl;}else{for (char *pCh = pStart; *pCh != '\0'; pCh++){if (!CheckIfExist(pStart, pCh)){//将首字符与其后字符交换SwitchToFront(pStart, pCh);//增加首字符指针,递归遍历后面的字符串PermutationReversely(pStr, pStart + 1);//将首字符回归原位,为后续字符交换做准备SwitchToFront(pStart, pCh);}}}
}
字符串组合
题目
输入一个字符串,输出该字符串的所有组合。比如输入abc,则输出 a, b, c, ab, ac, bc, abc
思路
- 假设字符串的长度为 n,那么首先要确定需要找出长度为 1~n的所有组合,采用循环。
- 假设当前确定的组合长度为 m,那么有两种求法。第一,可以选择首字符,然后在剩下的字符串中找出长度为 m - 1的组合,可以采用 vector 容器保存当前选择的字符;第二,不选择首字符,直接在剩下的字符串中找出长度为 m 的组合。采用递归方式。但应该注意,如果剩下的字符串的首字符之前已经出现过,则应该跳过此次递归,否则会重复出现。
- 判断递归边界条件。如果当前的字符串长度小于需要找到的组合长度,则应该直接返回。如果当前字符串的长度为0,则说明长度为 m 的组合寻找完毕,应该打印出 vector中的所有字符。
实现代码
//判断当前字符是否已经出现过
bool CheckIfExist(char* pStr, const char* pCh)
{char* p = pStr;while (p != pCh){if (*p == *pCh)return true;p++;}return false;
}//pStr - 当前需要确定组合的字符串
//pStart - 当前递归开始确定组合的字符串
//length - 需要确定的组合长度
//strVec - 保存的之前已经确定的字符
void PermutationReversely(char* pStr, char *pStart, int length, vector<char>& strVec)
{if (strlen(pStart) < length)return;if (!length){for (int i = 0; i < strVec.size(); i++){cout << strVec[i];}cout << endl;return;}strVec.push_back(*pStart);PermutationReversely(pStr, pStart + 1, length - 1, strVec);strVec.pop_back();//当下一个开始的字符串在之前没有出现时,才会递归if (!CheckIfExist(pStr, pStart + 1)){PermutationReversely(pStr, pStart + 1, length, strVec);}
}//主函数
void Permutation(char* pStr)
{if (!pStr || *pStr == '\0')return;int maxLength = strlen(pStr);vector<char> strVec;for (int length = 1; length <= maxLength; length++){PermutationReversely(pStr, pStr, length, strVec);}
}
八皇后问题
问题
在 8 乘 8 的国际象棋上拜访8个皇后,要求每个皇后不能处于同一行,不能处于同一列,且不能位于同一对角线,问有多少种摆放方法。
解题思路
这就是一个排列问题。
- 每个皇后不能处于同一行,那么一定每一行都有一个皇后。所以定义一个数组 ColunmIndex[8],ColumnIndex[i]表示第 i 行皇后的列坐标。
- ColumnIndex[8] 初始化为{0, 1, 2, 3, 4, 5 ,6, 7}。这样它们就满足了不位于同一行,和同一列
- 最终的解就是 ColumnIndex 数组的所有全排列中,满足皇后不位于同一对角线的,即满足:abs(i - j) != abs(ColumnIndex[i] - ColumnIndex[j])。
字符串全排列与组合算法以及八皇后问题相关推荐
- 回溯算法解决八皇后_4皇后问题和使用回溯算法的解决方案
回溯算法解决八皇后 4-皇后问题 (4 - Queen's problem) In 4- queens problem, we have 4 queens to be placed on a 4*4 ...
- 全排列算法(无重复数字全排列/有重复数字全排列)/ 组合算法/ 求子集算法
写在前面 全排列 1 无重复数字全排列 1.1 紫书版本 1.2 回溯法 2 有重复数字全排列 复盘易错点(可跳过) 写在前面 很久很久以前就想写的一篇博客,因为懒一直没开工,但是学习全排列算法算是我 ...
- 数据结构与算法 / 回溯算法(八皇后、0 - 1 背包)
回溯算法,顾名思义,就是在没有得到最优解的前提下,不断的返回至前面的岔路口位置,重新选择,直至遍历了所有的情况或者得到的预期最优解的情况下再结束. 与贪心算法不同的是,回溯算法理论上是可以得到最优解, ...
- 回溯算法-03八皇后问题
八皇后问题 简介 回溯法的经典问题. 问题描述 有8*8=64个格子,每个格子里面可以放一个棋子,现在要求任意两个棋子不在一条横向.纵向或者斜向的直线上. 问题分析 显然,每一行.每一列都只有一个棋子 ...
- 数据结构 - 递归 回溯算法(八皇后问题)
游戏地址自己写完了可以根据结果去测试一下. 算法分析 八皇后问题算法思路分析 1)第一个皇后先放第一行第一列 2)第二个皇后放在第二行第一列.然后判断是否OK, 如果不OK,继续放在.第二列.第三列. ...
- 爬山法、随机重启爬山法、模拟退火算法对八皇后问题和八数码问题的性能测试...
代码地址:https://github.com/laiy/AI/tree/master/awesome-search 一些前提: 1. 首先要明确这些算法并不是用于解决传统的搜索问题的(环境是可观察的 ...
- 回溯算法解决八皇后问题(JAVA实现)
送给程序猿们一句话 <拥有水滴石穿的坚持:懂得聚沙成塔的积累:磨练坚韧不拔的意志:学习脚踏实地的奋斗:提升立世做人的技巧:突破自我设限的障碍.> 文章目录 背景 问题解决 思路 什么是回溯 ...
- 算法总结——八皇后问题(三种解法)
问题描述 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8 ...
- 用递归思想和回溯算法解决八皇后问题(java实现)
八皇后问题 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处 ...
最新文章
- (转载)Linux信息资源
- Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解
- HDU2521 反素数【因子数量+打表】
- word通配符使用法详解
- 这九张动态图诠释什么是自然与科技的完美结合
- Flink : Cannot find compatible factory for specified execution.target (=local)
- Android生命周期帮助类,Android Service类与生命周期详细介绍_Android_脚本之家
- Python socket UDP
- CSS中min-height:100%问题
- 拓端tecdat|R语言中的多类别问题的绩效衡量:F1-score 和广义AUC
- 爬虫(二)-创建项目应用
- 2017百度之星资格赛总结
- 分享一下个人3年的运维经验
- python wheel是什么意思_python中wheel指的是什么
- 小白自学Java后端学习计划(附带学习视频)
- 微软中国CTO:手机里装的App一上网基本等于裸奔
- 移动端开发之Web App开发
- golang中结构体转成xml格式
- 网页素材大宝库:15套精美的用户头像图标素材
- 关于python的基础语法
热门文章
- Android9.0 Launcher启动Activity详解(一)
- 2013年山东省第四届ACM大学生程序设计竞赛 Problem I Thrall’s Dream 图,2n遍dfs
- 中央民族大学计算机房,中央民族大学第九届大学生人文知识竞赛 暨北京市第九届大学生人文知识竞赛选拔赛通知...
- Java面向对象之子类方法重写
- 利用Java计算多少次纸才能对折出珠峰高度
- cortellis数据库价格与价值分析
- 在线工作坊 | 人工智能之 AI on Azure
- 计算机科学转金融工程,计算机如何转金融与金融工程
- UWP控件与DataBind
- python中syntaxerror什么意思_在Python中,“SyntaxError:调用'print'时缺少括号”是什么意思?...