• 【九章斩题录】Leetcode:判定是否互为字符重排(C/C++)


        


    面试题 01.02. 判定是否互为字符重排

    ✅ 模板:C++

    1. class Solution {
    2. public:
    3. bool CheckPermutation(string s1, string s2) {
    4. }
    5. };


    「 法一 」排序

    💡 思路:看到题目中说 "重新排列后能否变成另一个字符串",等等……重新排列?

    我勒个豆,这题直接 sort 两下不就秒了?

    排序完比对一下两个字符串是不是一样的就行了:

    1. class Solution {
    2. public:
    3. bool CheckPermutation(string s1, string s2) {
    4. sort(s1.begin(), s1.end()); // 排s1
    5. sort(s2.begin(), s2.end()); // 排s2
    6. return s1 == s2 ? true : false; // 对比
    7. }
    8. };

    写完了,然后想了想应该可以再优化一下,如果长度不相等那必然不能重排。

    而且好像也没必要用三目,直接 return 表达式就行。

    1. class Solution {
    2. public:
    3. bool CheckPermutation(string s1, string s2) {
    4. if (s1.size() != s2.size()) { // 检查一下
    5. return false;
    6. }
    7. sort(s1.begin(), s1.end());
    8. sort(s2.begin(), s2.end());
    9. return s1 == s2; // 脑抽用三目,忘了可以直接返回了。
    10. }
    11. };

    哈哈哈搞定了,sort 排序时间复杂度为 O(nlogN)" role="presentation">O(nlogN),比较用了 O(n)" role="presentation">O(n),所以时间复杂度为:

    O(nlogN)+O(n)=O(nlogN)" role="presentation">O(nlogN)+O(n)=O(nlogN)

     用 sort 轻松将该题斩于马下……


    「 法二 」HashMap!uh~

    💡 思路:好像也可以用哈希,HHHHHHHHHash Map!ur!

    分别 for 滚一轮 s1 和 s2 的元素:

    • 统计字符串 s1 各字符数量,遇到 +1
    • 统计字符串 s2 各字符数量,遇到 -1
    • 遍历 s1, s2 中各字符的数量差,若 s1, s2 中某字符的数量不一致,则不互为重排。

    如果都对上了,就是 "抵消" 了,看代码:

    1. class Solution {
    2. public:
    3. bool CheckPermutation(string s1, string s2) {
    4. if (s1.size() != s2.size()) { // 提前解决s1 s2长度不一样的情况
    5. return false;
    6. }
    7. unordered_map<char, int> hash;
    8. for (char e : s1) { // 一边加
    9. hash[e] += 1;
    10. }
    11. for (char e : s2) { // 另一边减
    12. hash[e] -= 1;
    13. }
    14. for (auto kv : hash) {
    15. if (kv.second != 0) {
    16. return false;
    17. }
    18. }
    19. return true;
    20. }
    21. };

    在这里,我特别想感谢一下 auto for 的存在,如果没有 auto for,那么会非常的窒息……

    1. for (unordered_map<char, int>::iterator it = hash.begin();
    2. \ it != hash.end(); it++) {
    3. if (it->second != 0) {
    4. return false;
    5. }
    6. }

    喝完咖啡回来想了想,好像也不用再迭代器判断一遍,s2 的 for 当前元素 -1 后发现<0 的话就可以直接 return false 了,<0 肯定是因为 s1 里压根就没出现过这个字符 (没记录到哈希桶里)……   但这样就 必须要对 s1 和 s2 进行长度判断,长度不同直接 return false。

    1. class Solution {
    2. public:
    3. bool CheckPermutation(string s1, string s2) {
    4. if (s1.size() != s2.size()) {
    5. return false;
    6. }
    7. unordered_map<char, int> hash;
    8. for (char& e : s1) { // 一边加
    9. hash[e] += 1;
    10. }
    11. for (char& e : s2) { // 另一边减
    12. hash[e] -= 1;
    13. if (hash[e] < 0) {
    14. return false;
    15. }
    16. }
    17. return true;
    18. }
    19. };

    测试,if (<0) 就不能重排。

    1. s1 = a a b b c
    2. s2 = a a b c c
    3. 入桶(+):a:2 b:2 c:1
    4. 检查(-):a:0 b:1 c:-1
    5. return false;
    6. s1 = a b c
    7. s2 = b c a
    8. 入桶(+):a:1 b:1 c:1
    9. 检查(-):a:0 b:0 c:0
    10. return true;
    11. s1 = a b c
    12. s2 = b a d
    13. 入桶(+):a:1 b:1 c:1
    14. 检查(-):a:0 b:0 d:-1
    15. return false;

    也可以直接定义一个维护 128 个字符的数组:

    1. class Solution {
    2. public:
    3. bool CheckPermutation(string s1, string s2) {
    4. if (s1.size() != s2.size()) {
    5. return false;
    6. }
    7. vector<int> table(128, 0);
    8. for (char& ch : s1) {
    9. table[ch]++;
    10. }
    11. for (char& ch : s2) {
    12. table[e]--;
    13. if (table[e] < 0) {
    14. return false;
    15. }
    16. }
    17. return true;
    18. }
    19. };

    1. 📌 [ 笔者 ]   王亦优
    2. 📃 [ 更新 ]   2023.
    3. ❌ [ 勘误 ]   /* 暂无 */
    4. 📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,
    5. 本人也很想知道这些错误,恳望读者批评指正!

    📜 参考资料 

    C++reference[EB/OL]. []. http://www.cplusplus.com/reference/.

    Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

    百度百科[EB/OL]. []. https://baike.baidu.com/.

    牛客网. 剑指offer 题解 [EB/OL]. []. https://www.nowcoder.com/exam/oj/ta?tpId=13.

  • 相关阅读:
    解决报错:fatal: Authentication failed for ‘https://github.com/*/*.git/‘
    Java实战:Spring Boot自动配置原理与定制
    Worthington优化技术:细胞定量
    【Node】Node实现网络编程
    中国为什么要发展人工智能
    中国五氯化磷市场调研与投资预测报告(2022版)
    浅谈企业信息化安全建设中的三大误区
    构建RAG应用-day05: 如何评估 LLM 应用 评估并优化生成部分 评估并优化检索部分
    SpringSecurity Oauth2实战 - 09 自定义SpEL权限表达式
    tidymodels用于机器学习的一些使用细节
  • 原文地址:https://blog.csdn.net/weixin_50502862/article/details/132853297