zoukankan      html  css  js  c++  java
  • 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;
        }
    };
  • 相关阅读:
    codeforces #601 div2 ABC~E1
    codeforces #600 div2 ABCD
    图形学 三次Hermite曲线绘制实现代码 javascript:es6+h5:canvas
    最小生成树(Prim / Kruskal)
    拓扑排序【Kahn算法(bfs)和dfs求拓扑序列及判环】
    Cow Traffic(正反向建图+DAG拓扑排序)
    JAVA大数
    【C/C++】关于strstr函数和c_str()函数
    【C/C++】关于函数调用传递实参
    2019上海icpc网络赛B. Light bulbs(思维+差分)
  • 原文地址:https://www.cnblogs.com/Bella2017/p/11132425.html
Copyright © 2011-2022 走看看