- 问题一:https://www.nowcoder.com/practice/f0069cfcd42649e3b6b0c759fae8cde6?tpId=46&tqId=29148&tPage=3&rp=3&ru=/ta/leetcode&qru=/ta/leetcode/question-ranking
- 这个题目意思是给定一个排列数组,然后要求出下一个排列的数组。比如说1234->1243 1243->1324等等。这个题目是一个全排列的题目,但是只是要求出后一个排列。STL容器中有一个next_permutation函数是来求出数组的所有排列的。
- STL里面的next_permutation算法的主要思路:在当前序列中,从尾端往前寻找两个相邻元素,前一个记为*i,后一个记为*ii,并且满足*i < *ii。然后再从尾端寻找另一个元素*j,如果满足*i < *j,即将第i个元素与第j个元素对调,并将第ii个元素之后(包括ii)的所有元素颠倒排序,即求出下一个序列了。
- next_permutation函数测试代码
-
#include <iostream> #include <algorithm> #include <vector> using namespace std; int main(){ vector<int> str; for(int i=1; i<5; i++) str.push_back(i); //这里我是默认的将输入数组变成了升序排序,如果要求全排列必须重新排序。
sort(str.begin(), str.end()); while(next_permutation(str.begin(), str.end())){ for(int i=0; i<4; i++) cout<<str[i]; cout<<endl; } } - 测试结果
-
- 好回到这个题目:主要思路和这个函数的解法是类似的,给出代码
class Solution { public: void nextPermutation(vector<int> &num) { int size = num.size(); if (size < 2) return ; int i, j; for (i=size-2; i>=0; --i)//这个是从后往前找到相邻的两个数,其中第i个数小于第i+1个数 if (num[i] < num[i+1]) break; for (j=size-1; j>i; --j)//这个是从后找到一个大于第i个数的j if (num[j] > num[i]) break; if (i>=0) swap(num[i], num[j]);//交换第i个数和第j个数 reverse(num.begin()+i+1, num.end());//再将第i+1后面的所有数字进行翻转,就形成了下一个序列 } };
- 这个题目意思是给定一个排列数组,然后要求出下一个排列的数组。比如说1234->1243 1243->1324等等。这个题目是一个全排列的题目,但是只是要求出后一个排列。STL容器中有一个next_permutation函数是来求出数组的所有排列的。
- 问题二:https://www.nowcoder.com/practice/4bcf3081067a4d028f95acee3ddcd2b1?tpId=46&tqId=29133&tPage=1&rp=1&ru=/ta/leetcode&qru=/ta/leetcode/question-ranking
- 这个题目是求全排列的问题,其实只要稍微处理一下上面那个求后一个排列的函数,让他来个bool类型的返回值,(这里有一个重点:必须要是升序数组哦)。这样就可以实现了。
- 代码:
class Solution { public: bool nextPermutation(vector<int> &num) { int size = num.size(); if (size < 2) return false; int i, j; for (i=size-2; i>=0; --i)//这个是从后往前找到相邻的两个数,其中第i个数小于第i+1个数 if (num[i] < num[i+1]) break; for (j=size-1; j>i; --j)//这个是从后找到一个大于第i个数的j if (num[j] > num[i]) break; if (i>=0) swap(num[i], num[j]);//交换第i个数和第j个数 reverse(num.begin()+i+1, num.end());//再将第i+1后面的所有数字进行翻转,就形成了下一个序列 return i>=0; } vector<vector<int> > permute(vector<int> &num) { vector<vector<int> > res; sort(num.begin(), num.end());//这里是求全排列,所以我们需要将数组重新排序才能得出 do{ res.push_back(num); }while(nextPermutation(num)); return res; } };
- 问题三:用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列,如 abc 的全排列: abc, acb, bca, dac, cab, cba
- 方法一:全排列的递归实现(不包含重复的元素)
- 思路:为方便起见,用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> #include <stdio.h> void Permutation(char* pStr, char* pBegin) { assert(pStr && pBegin); if(*pBegin == '
- 方法一:全排列的递归实现(不包含重复的元素)