【LeetCode】数组排列问题(permutations)(附加next_permutation解析)
描述
Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路一:递归
利用STL的函数swap()来交换数组的元素
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> ans;
backtracing(nums, , ans);
return ans;
}
void backtracing(vector<int>& nums, int begin,vector<vector<int>>& res){
if(begin>=nums.size()){
res.push_back(nums);
return;
}
for(int i =begin;i<nums.size();++i){
swap(nums[begin], nums[i]);
backtracing(nums, begin + , res);
swap(nums[begin], nums[i]);
}
}
};
思路二 next_permutation方法
利用STL的库函数: next_permutation 取得下一个排列
需要#include <algorithm>
class Solution {
public:
vector<vector<int>> permute(vector<int>& num) {
vector<vector<int> > ans;
sort(num.begin(), num.end());
ans.push_back(num);
while(next_permutation(num.begin(), num.end())) //求出下一个排列组合
ans.push_back(num);
return ans;
}
};
附加:next_permutation解析
在STL中,除了next_permutation外,还有一个函数prev_permutation,两者都是用来计算排列组合的函数。前者是求出下一个排列组合,而后者是求出上一个排列组合。所谓“下一个”和“上一个”,例如:对序列 {a, b, c},每一个元素都比后面的小,按照字典序列,固定a之后,a比bc都小,c比b大,它的下一个序列即为{a, c, b},而{a, c, b}的上一个序列即为{a, b, c},同理可以推出所有的六个序列为:{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a},其中{a, b, c}没有上一个元素,{c, b, a}没有下一个元素。
next_permutation的函数原型如下:
template<class BidirectionalIterator>
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last
);
template<class BidirectionalIterator, class BinaryPredicate>
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last,
BinaryPredicate _Comp
);
对于第二个重载函数的第三个参数,默认比较顺序为小于。如果找到下一个序列,则返回真,否则返回假。
函数实现原理如下:
在当前序列中,从尾端往前寻找两个相邻元素,前一个记为*i,后一个记为*ii,并且满足*i < *ii。
然后再从尾端寻找另一个元素*j,如果满足*i < *j,即将第i个元素与第j个元素对调,并将第ii个元素之后(包括ii)的所有元素颠倒排序,即求出下一个序列了。
如果*i>=j, j--,直到*i < *j。因为目的是将i处较小元素与j处仅比i处元素大的调换,比如下面:
12345==>12354,之后,然后执行next_permutation,经过for循环,i在前ii在后,ii要比i大,从后遍历,这时i=3,ii=5,j=4,所以i和j调换,成为12453,然后ii后的元素进行reverse,得到:12435,所以:
12354的后一个元素是12435.
template<class BidirectionalIterator>
bool next_permutation(
BidirectionalIterator first,
BidirectionalIterator last
)
{
if(first == last)
return false; //空序列 BidirectionalIterator i = first;
++i;
if(i == last)
return false; //一个元素,没有下一个序列了 i = last;
--i; for(;;) {
BidirectionalIterator ii = i;
--i;
if(*i < *ii) {
BidirectionalIterator j = lase;
while(!(*i < *--j)); iter_swap(i, j);
reverse(ii, last);
return true;
} if(i == first) {
reverse(first, last); //全逆向,即为最小字典序列,如cba变为abc
return false;
}
} }
prev_permutation实现类似,就是反向查找
小结
用next_permutation和prev_permutation求排列组合很方便,但是要记得包含头文件#include <algorithm>。
虽然最后一个排列没有下一个排列,用next_permutation会返回false,但是使用了这个方法后,序列会变成字典序列的第一个,如cba变成abc。prev_permutation同理。
【LeetCode】数组排列问题(permutations)(附加next_permutation解析)的更多相关文章
- 数组排列组合问题——BACKTRACKING
BACKTRACKING backtracking(回溯法)是一类递归算法,通常用于解决某类问题:要求找出答案空间中符合某种特定要求的答案,比如eight queens puzzle(将国际象棋的八个 ...
- Leetcode数组题*3
目录 Leetcode数组题*3 66.加一 题目描述 思路分析 88.合并两个有序数组 题目描述 思路分析 167.两数之和Ⅱ-输入有序数组 题目描述 思路分析 Leetcode数组题*3 66.加 ...
- Atitit main函数的ast分析 数组参数调用的ast astview解析
Atitit main函数的ast分析 数组参数调用的ast astview解析 1.1. Xxcls.main(new String[]{"","bb"}) ...
- Java利用递归算法统计1-6的数组排列组合数
Java利用递归算法统计1-6的数组排列组合数 1.设计源码 /** * @Title:ArrayCombination.java * @Package:com.you.data * @Descrip ...
- JavaScript 二维数组排列组合2
<html> <head> <title>二维数组排列组合</title> </head> <body> <div id= ...
- JavaScript 二维数组排列组合
<html> <head> <title>二维数组排列组合</title> </head> <body> <div id= ...
- 5_PHP数组_3_数组处理函数及其应用_7_数组排列函数
以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. 数组排列函数 1. sort() 函数 程序: <?php $array = array("img ...
- leetcode.数组.16最接近的三数之和-java
1. 具体题目 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答案 ...
- leetcode.数组.287寻找重复数-Java
1. 具体题目 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数,找出这个重复的数. 示例 1: ...
随机推荐
- android tooggle button
1 http://stackoverflow.com/questions/9938315/toggle-button-in-iphone-style 2 http://blog.csdn.net/bi ...
- <LeetCode OJ> 155. Min Stack
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. pu ...
- iOS GCD不同场景的使用比較
/** * async -- 并发队列 * 会创建线程.一般同一时候开多条 * 并发运行任务 */ <span style="font-size:14px;"> ...
- Android基础笔记(十八)- Fragment
博客的感悟终点-開始 什么是Fragment 加入fragment到Activity的两种方式 Fragment的生命周期 Fragment的向下兼容 Fragment之间的通信 博客的感悟,终点-開 ...
- Hdu 5288 OO’s Sequence 2015多小联赛A题
OO's Sequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- 《Lucene in Action》(第二版) 第一章节的学习总结 ---- 用最少的代码创建索引和搜索
第一章节是介绍性质,但是通过这一章节的学习,我理解到如下概念: 1.Lucene由两部分组成:索引和搜索.索引是通过对原始数据的解析,形成索引的过程:而搜索则是针对用户输入的查找要求,从索引中找到匹配 ...
- 配置LANMP环境(9)-- 安装Git与vsftp
一.安装Git 检查是否已经安装 git --version 安装 yum -y install git 二.安装vsftp 检查是否已经安装 yum list installed vsftpd 安装 ...
- 01 mongodb 的特点
mongoDB 介绍(特点.优点.原理) 介绍:MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. 特点:高性能.易部署.易使用,存 ...
- Oracle Data Provider for .NET的使用(二)-驱动更换与注意事项
上篇说过了ODP的安装与配置 ,但是个人比较喜欢托管类型的,毕竟非托管类型的,因为考虑到会有用户或者是服务器或者是开发人员有32位的机器,就要强制编译平台平台为32位,只因为这个驱动,有点让人不愉快了 ...
- vue实践---vue不依赖外部资源实现简单多语
vue使用多语,最常见的就是 vue-i18n, 但是如果开发中的多语很少,比如就不到10个多语,这样就没必要引入vue-i18n了, 引入了反正导致代码体积大了,这时候单纯用vue实现多语就是比较好 ...