#include
template <class BidirectionalIterator>
bool next_permutation (BidirectionalIterator first, BidirectionalIterator last);
template <class BidirectionalIterator, class Compare>
bool next_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare comp);
next_permutation
原地将 [first, last) 中的元素重新排列为下一个字典序更大的排列。若当前排列存在下一个更大的排列,则返回 true,并生成下一个更大排列;若不存在,则返回 false,按从小到大的顺序排列。
vector<string> strs{"aba", "aab", "abb", "ac"};
sort(strs.begin(), strs.end()); // aab aba abb ac
next_permutation(strs.begin(), strs.end()); // aab aba ac abb
问题:生成一个不包含重复元素序列的所有排列组合。
template<typename T>
vector<vector<T>> getAllPermutation(vector<T> sequences) {
sort(sequences.begin(), sequences.end());
vector<vector<T>> ans;
do {
ans.emplace_back(sequences);
} while (next_permutation(sequences.begin(), sequences.end()));
return ans;
}
int main()
{
vector<int> nums(3);
iota(nums.begin(), nums.end(), 1);
vector<vector<int>> permutations = getAllPermutation(nums);
for (auto& per : permutations) {
for_each(per.begin(), per.end(), [](int e){
cout << e << " ";
});
cout << endl;
}
cout << endl;
}
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
问题:生成从N个元素中取M个的所有组合(来自陈硕《Linux多线程服务端编程》)
从 7 个不同元素中取出 3 个元素的所有组合。
思路:对序列 [1, 1, 1, 0, 0, 0, 0] 做全排列,对于每个排列,输出数字1对应的位置上的元素。
vector<vector<int>> getPermutations(vector<int> nums, int m) {
int n = nums.size();
vector<int> indices(n, 0);
fill(indices.begin(), indices.begin() + m, 1);
sort(indices.begin(), indices.end());
vector<vector<int>> ans;
do {
vector<int> temp;
for (int i = 0; i < n; i++) {
if (indices[i]) {
temp.emplace_back(nums[i]);
}
}
ans.emplace_back(temp);
} while (next_permutation(indices.begin(), indices.end()));
return ans;
}
#include
template <class ForwardIterator, class T>
void iota (ForwardIterator first, ForwardIterator last, T val);
iota
为 [first, last)
范围内的每个元素分配连续递增的 val
,即每次写入一个 val
后,++val
递增一下。对于 int 类型,等价如下:
for (int i = first; i < last; i++) {
nums[i] = val++;
}
iota 的一种应用场景为,数组排序时通过下标位置体现排序后的结果,代码示例如下:
vector<int> nums = { 4,3,1,5,9,8,7,0,2,6 };
vector<int> indices(nums.size());
// 生成对应的下标
iota(indices.begin(), indices.end(), 0);
sort(indices.begin(), indices.end(), [&](int i, int j) {
return nums[i] < nums[j];
});
**leetcode** 26. 删除有序数组中的重复项
给你一个 升序排列 的数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
int removeDuplicates(vector<int>& nums) {
auto it = unique(nums.begin(), nums.end(), [](int i, int j){
return i == j;
});
return it - nums.begin();
}
问题:去除字符之间多余的空格(来自陈硕《Linux多线程服务端编程》
string strs{"hello world old leetcode"};
auto last = unique(strs.begin(), strs.end(), [](int i, int j){
return i == ' ' && j == ' ';
});
strs.erase(last, strs.end());
// hello world old leetcode