使用STL algorithm 解决一些算法问题

使用 next_permutation 生成排列和组合

#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;
}

使用 iota 生成一个连续递增的序列

#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];
});

使用 unique 去除连续序列中重复的元素

**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

你可能感兴趣的:(cpp,刷题,算法,c++)