leetcode 575:Distribute Candies, 266: Palindrome Permutation, 46:Permutations

思路:给我们一堆糖,每种糖的个数不定,分给两个人,让我们求其中一个人能拿到的最大的糖的种类数。那么我们想,如果总共有n个糖,平均分给两个人,每人得到n/2块糖,那么能拿到的最大的糖的种类数也就是n/2种,不可能再多,只可能再少。那么我们要做的就是统计出总共的糖的种类数,如果糖的种类数小于n/2,说明拿不到n/2种糖,最多能拿到的种类数数就是当前糖的总种类数,明白了这点就很容易了,利用集合set的自动去重复特性来求出糖的种类数,然后跟n/2比较,取二者之中的较小值返回即可。

class Solution {
public:
    int distributeCandies(vector<int>& candies) {
        unordered_set<int> s;
        for(int candy : candies)
            s.insert(candy);
        return min(s.size(), candies.size()/2);
    }
};

这道题让我们判断一个字符串的全排列有没有是回文字符串的,那么根据题目中的提示,我们分字符串的个数是奇偶的情况来讨论,如果是偶数的话,由于回文字符串的特性,每个字母出现的次数一定是偶数次,当字符串是奇数长度时,只有一个字母出现的次数是奇数,其余均为偶数,那么利用这个特性我们可以使用 unordered_map 建立每个字母和其出现次数的映射,然后我们遍历 HashMap,统计出现次数为奇数的字母的个数,那么只有两种情况是回文数,第一种是没有出现次数为奇数的字母,再一个就是字符串长度为奇数,且只有一个出现次数为奇数的字母。

class Solution {
public:
    bool canPermutePalindrome(string s) {
        unordered_map<char, int> m;
        int cnt = 0;
        for (auto a : s) ++m[a];
        for (auto a : m) {
            if (a.second % 2 == 1) ++cnt;
        }
        return cnt == 0 || (s.size() % 2 == 1 && cnt == 1);
    }
};

解法一:使用C++中的 next_permutation() 函数,头文件是#include<algorithm>

注意:要先对数组进行从小到大排序。

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());  //使用next_permutation()之前需要排序
        do{
            vector<int> out(nums);
            res.push_back(out);
        }while(next_permutation(nums.begin(), nums.end()));
        return res;
    }
};

解法二:递归+回溯(backtracking)

 

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> out;
        vector<int> visit(nums.size(), 0);    
        search(nums, visit, out, res);
        return res;
    }
    
    void search(vector<int>& nums, vector<int>& visit, vector<int>& out, vector<vector<int>>& res){
        if(out.size()== nums.size()){
            res.push_back(out);
            return;
        }
        for(int i=0; i<nums.size();i++){
            if(visit[i]==0){
                visit[i] = 1;
                out.push_back(nums[i]);
                search(nums, visit, out, res);
                out.pop_back();
                visit[i] = 0;
            }    
        }
    }
};

Palindrome Permutation II 回文全排列之二

Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empty list if no palindromic permutation could be form.

For example:

Given s = "aabb", return ["abba", "baab"].

Given s = "abc", return [].

Hint:

  1. If a palindromic permutation exists, we just need to generate the first half of the string.
  2. To generate all distinct permutations of a (half of) string, use a similar approach from: Permutations II or Next Permutation.

 注意:string(n,char) 表示n个连续的char类型字符构成的string。

class Solution {
public:
    vector<string> generatePalindromes(string s) {
        vector<string> res;
        unordered_map<char, int> m;
        string t = "", mid = "";
        for (auto a : s) ++m[a];
        for (auto &it : m) {
            if (it.second % 2 == 1) mid += it.first;
            it.second /= 2;
            t += string(it.second, it.first);
            if (mid.size() > 1) return {};
        }
        permute(t, m, mid, "", res);
        return res;
    }
    void permute(string &t, unordered_map<char, int> &m, string mid, string out, vector<string> &res) {
        if (out.size() >= t.size()) {
            res.push_back(out + mid + string(out.rbegin(), out.rend()));
            return;
        } 
        for (auto &it : m) {
            if (it.second > 0) {
                --it.second;
                permute(t, m, mid, out + it.first, res);
                ++it.second;
            }
        }
    }
};
class Solution {
public:
    vector<string> generatePalindromes(string s) {
        vector<string> res;
        unordered_map<char, int> m;
        string t = "", mid = "";
        for (auto a : s) ++m[a];
        for (auto it : m) {
            if (it.second % 2 == 1) mid += it.first;
            t += string(it.second / 2, it.first);
            if (mid.size() > 1) return {};
        }
        sort(t.begin(), t.end());
        do {
            res.push_back(t + mid + string(t.rbegin(), t.rend()));
        } while (next_permutation(t.begin(), t.end()));
        return res;
    }
};

 

posted @ 2019-07-04 19:40  爱学英语的程序媛  阅读(199)  评论(0编辑  收藏  举报