leetcode 3035

leetcode 3035

题目

例子

思路

统计字符出现的频次,5个a(字符可以成为回文)。

将所有字符放在一起考虑,因为字符是可以任意移动。["aabb","a"] => ["abba", "a"]

只要奇数个字符的种类,不要超过字符数组的size就可以。

代码实现

cpp 复制代码
class Solution {
public:
    int maxPalindromesAfterOperations(vector<string>& words) {
        int ans =0;
        int total =0;
        int mask =0;

        for(auto & w:words){
            total += w.length();
            for(auto & ss: w){
                //确认字符是否是奇数,通过异或运算
                mask^=1<<(ss-'a');
            }
        }
        // __builtin_popcount函数统计二进制(mask)有多少个bit是1
        total -= __builtin_popcount(mask);

        sort(words.begin(), words.end(), [](string &a, string& b){ return a.length() < b.length();});
   
        for(auto & w:words){
            //已经减去奇数的部分了, 1/2 =0, 考虑到存在"a" 也是回文,需要对words进行排序
            total -= w.length()/2 *2;
            if(total < 0){
                break;
            }
            ans++;
        }

        return ans;
    }
};

分析

排序时间复杂度平均是0(nlogn)

__builtin_popcount

__builtin_popcount是GCC编译器提供的内建函数,用于计算一个整数中二进制表示中1的个数(即统计整数中1的个数)。

语法:

cpp 复制代码
int __builtin_popcount(unsigned int x);

参数:

  • x:要计算的整数值。

返回值:

  • 返回整数x中二进制表示中1的个数。

示例:

cpp 复制代码
#include <iostream>

int main() {
    unsigned int x = 15; // 二进制表示为 1111
    int count = __builtin_popcount(x); // 计算x中1的个数
    std::cout << "Number of set bits in " << x << ": " << count << std::endl;
    
    return 0;
}

注意:

  • __builtin_popcount函数只能接受unsigned int类型的参数,如果传入其他类型的参数,可能会导致编译错误。
  • 该函数在GCC编译器中可用,可能不适用于其他编译器。

使用__builtin_popcount函数可以高效地计算一个整数中1的个数,特别适用于位操作相关的算法和问题。

遍历

在这两种循环语句中,for(string s : words)for(auto &s : words)的区别在于变量s的类型和是否是引用类型。

  1. for(string s : words)

    • 这种写法会创建words中每个元素的副本,并将副本赋值给变量s。这意味着在循环体内对s的修改不会影响到words中的元素。
    • 这种写法适用于遍历容器中的元素,如果只需要访问元素而不修改它们,这种写法是合适的。
  2. for(auto &s : words)

    • 这种写法使用auto关键字推导出words中元素的类型,并将s声明为对应类型的引用。这样s将直接引用words中的元素,而不是创建副本。
    • 使用引用类型可以提高效率,避免不必要的内存拷贝操作。
    • 如果需要在循环中修改words中的元素,或者希望在循环外部访问修改后的元素,使用引用类型是更好的选择。

综上所述,for(string s : words)会创建元素的副本,而for(auto &s : words)会直接引用。

统计整数x中二进制表示中1的个数

要统计一个整数 x 中二进制表示中 1 的个数,可以使用以下方法:

cpp 复制代码
#include <iostream>

int countSetBits(int x) {
    int count = 0;
    while (x) {
        count += x & 1;
        x >>= 1;
    }
    return count;
}

int main() {
    int x = 25; // 二进制表示为 11001
    int numberOfOnes = countSetBits(x);
    std::cout << "Number of ones in binary representation of " << x << ": " << numberOfOnes << std::endl;
    
    return 0;
}

在上面的示例中,countSetBits 函数用于统计整数 x 中二进制表示中 1 的个数。该函数通过将 x 与 1 进行按位与操作,判断 x 的最低位是否为 1,然后将 x 右移一位,直到 x 变为 0。在每次循环中,如果 x 的最低位为 1,则 count 加一。最终返回 count 即为 x 二进制表示中 1 的个数。

main 函数中,我们给定一个整数 x 的值为 25(二进制表示为 11001),然后调用 countSetBits 函数统计其二进制表示中 1 的个数,并输出结果。

相关推荐
乌萨奇也要立志学C++11 小时前
【洛谷】BFS 求解最短路:从马的遍历到迷宫问题的实战解析
算法·宽度优先
老鼠只爱大米11 小时前
LeetCode经典算法面试题 #46:全排列(回溯、交换、剪枝等五种实现方案详细解析)
算法·leetcode·剪枝·回溯·全排列·stj算法
Dovis(誓平步青云)11 小时前
《滑动窗口算法:从 “暴力遍历” 到 “线性高效” 的思维跃迁》
运维·服务器·数据库·算法
_OP_CHEN11 小时前
【算法基础篇】(五十七)线性代数之矩阵乘法从入门到实战:手撕模板 + 真题详解
线性代数·算法·矩阵·蓝桥杯·c/c++·矩阵乘法·acm/icpc
天天爱吃肉821811 小时前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车
im_AMBER11 小时前
Leetcode 114 链表中的下一个更大节点 | 删除排序链表中的重复元素 II
算法·leetcode
xhbaitxl12 小时前
算法学习day38-动态规划
学习·算法·动态规划
多恩Stone12 小时前
【3D AICG 系列-6】OmniPart 训练流程梳理
人工智能·pytorch·算法·3d·aigc
历程里程碑12 小时前
普通数组----轮转数组
java·数据结构·c++·算法·spring·leetcode·eclipse
pp起床12 小时前
贪心算法 | part02
算法·leetcode·贪心算法