[LeetCode] 266. Palindrome Permutation 回文全排列

本文介绍了一种算法,用于判断给定字符串的任意排列是否能构成回文串。通过统计字符频率并检查奇数次字符数量,提供了多种语言实现方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a string, determine if a permutation of the string could form a palindrome.

For example,
"code" -> False, "aab" -> True, "carerac" -> True.

Hint:

    1. Consider the palindromes of odd vs even length. What difference do you notice?
    2. Count the frequency of each character.
    3. If each character occurs even number of times, then it must be a palindrome. How about character which occurs odd number of times?

给一个字符串,判断它的全排列中是否有回文。

解法:基本原理就是,如果字符串长度为单数,那么可以有一个字符是单数,其它出现的字符必须都是双数。如果字符串长度为偶数,那么所有的字符都必须是双数,才能组成回文。

具体实现方法可以有多种。

 Java:

public class Solution {
    public boolean canPermutePalindrome(String s) {
        Map<Character, Integer> map = new HashMap<Character, Integer>();
        // 统计每个字符的个数
        for(int i = 0; i < s.length(); i++){
            char c = s.charAt(i);
            Integer cnt = map.get(c);
            if(cnt == null){
                cnt = new Integer(0);
            }
            map.put(c, ++cnt);
        }
        // 判断是否只有不大于一个的奇数次字符
        boolean hasOdd = false;
        for(Character c : map.keySet()){
            if(map.get(c) % 2 == 1){
                if(!hasOdd){
                    hasOdd = true;
                } else {
                    return false;
                }
            }
        }
        return true;
    }
}

Java:

public class Solution {
    public boolean canPermutePalindrome(String s) {
        Set<Character> set = new HashSet<Character>();
        for(int i = 0; i < s.length(); i++){
            // 出现的第偶数次,将其从Set中移出
            if(set.contains(s.charAt(i))){
                set.remove(s.charAt(i));
            } else {
            // 出现的第奇数次,将其加入Set中
                set.add(s.charAt(i));
            }
        }
        // 最多只能有一个奇数次字符
        return set.size() <= 1;
    }
} 

Java:

public class Solution {
    public boolean canPermutePalindrome(String s) {
        if (s == null) return false;
        Set<Character> set = new HashSet<>(s.length());
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (!set.add(c)) set.remove(c);
        }
        return set.size() < 2;
    }
}  

Python:

class Solution(object):
    def canPermutePalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        """
        d = {}
        for i in s:
            d[i] = d.get(i, 0) + 1

        count = 0
        for i in d.values():
            if i % 2 != 0:
                count += 1
            if count > 1:
                return False
                
        return True

Python:

class Solution(object):
    def canPermutePalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        """
        oddChars = set()

        for c in s:
            if c in oddChars:
                oddChars.remove(c)
            else:
                oddChars.add(c)

        return len(oddChars) <= 1  

Python:

class Solution(object):
    def canPermutePalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        """
        return sum(v % 2 for v in collections.Counter(s).values()) <  2

C++:

class Solution {
public:
    bool canPermutePalindrome(string s) {
        bitset<256> bits;
        for (const auto& c : s) {
            bits.flip(c);
        }
        return bits.count() < 2;
    }
};

C++:

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

C++:

class Solution {
public:
    bool canPermutePalindrome(string s) {
        set<char> t;
        for (auto a : s) {
            if (t.find(a) == t.end()) t.insert(a);
            else t.erase(a);
        }
        return t.empty() || t.size() == 1;
    }
};

  

类似题目:

[LeetCode] 267. Palindrome Permutation II 回文全排列 II 

   

All LeetCode Questions List 题目汇总

 

转载于:https://www.cnblogs.com/lightwindy/p/8629443.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值