【Leetcode】1002. 查找共用字符

Given a string array words, return an array of all characters that show up in all strings within the words (including duplicates). You may return the answer in any order.

Example 1:

Input: words = ["bella","label","roller"]
Output: ["e","l","l"]

Example 2:

Input: words = ["cool","lock","cook"]
Output: ["c","o"]

Constraints:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 100
  • words[i] consists of lowercase English letters.

Thought:

  • 哈希表
  • 但是没实现出来
  • 提供大佬的AC
class Solution {
    
    
public:
    vector<string> commonChars(vector<string>& A) {
    
    
        vector<string> result;
        if (A.size() == 0) return result;
        int hash[26] = {
    
    0}; // 用来统计所有字符串里字符出现的最小频率
        for (int i = 0; i < A[0].size(); i++) {
    
     // 用第一个字符串给hash初始化
            hash[A[0][i] - 'a']++;
        }

        int hashOtherStr[26] = {
    
    0}; // 统计除第一个字符串外字符的出现频率
        for (int i = 1; i < A.size(); i++) {
    
    
            memset(hashOtherStr, 0, 26 * sizeof(int));
            for (int j = 0; j < A[i].size(); j++) {
    
    
                hashOtherStr[A[i][j] - 'a']++;
            }
            // 更新hash,保证hash里统计26个字符在所有字符串里出现的最小次数
            for (int k = 0; k < 26; k++) {
    
    
                hash[k] = min(hash[k], hashOtherStr[k]);
            }
        }
        // 将hash统计的字符次数,转成输出形式
        for (int i = 0; i < 26; i++) {
    
    
            while (hash[i] != 0) {
    
     // 注意这里是while,多个重复的字符
                string s(1, i + 'a'); // char -> string
                result.push_back(s);
                hash[i]--;
            }
        }

        return result;
    }
};

看了下官方题解

AC

/*
 * @lc app=leetcode.cn id=1002 lang=cpp
 *
 * [1002] 查找共用字符
 */

// @lc code=start
class Solution {
    
    
public:
    vector<string> commonChars(vector<string>& words) {
    
    
        vector<int> minfreq(26, INT_MAX);
        vector<int> freq(26);
        for(const string& word : words)
        {
    
    
            fill(freq.begin(), freq.end(), 0);
            for(char ch : word)
            {
    
    
                freq[ch - 'a']++;
            }
            for(int i = 0; i < 26; i++)
            {
    
    
                minfreq[i] = min(minfreq[i], freq[i]);
            }
        }

        vector<string> ans;
        for(int i = 0; i < 26; i++)
        {
    
    
            for(int j = 0; j < minfreq[i]; j++)
            {
    
    
                ans.emplace_back(1, i + 'a');
            }
        }
        return ans;
    }
};
// @lc code=end

AC


std::fill 函数用于填充指定范围的元素,即用给定的值替换指定范围的所有元素。其语法如下:

template< class ForwardIt, class T >
void fill( ForwardIt first, ForwardIt last, const T& value );

其中,firstlast 参数指定了要填充的元素范围,value 参数则是要赋给每个元素的值。

例如,以下代码将整个数组 arr 中的元素都置为 0:

int arr[10];
std::fill(std::begin(arr), std::end(arr), 0);

如果要填充的元素类型是类对象,则需要确保该类具有有效的赋值运算符。std::fill 函数用于填充指定范围的元素,即用给定的值替换指定范围的所有元素。其语法如下:

template< class ForwardIt, class T >
void fill( ForwardIt first, ForwardIt last, const T& value );

其中,firstlast 参数指定了要填充的元素范围,value 参数则是要赋给每个元素的值。

例如,以下代码将整个数组 arr 中的元素都置为 0:

int arr[10];
std::fill(std::begin(arr), std::end(arr), 0);

如果要填充的元素类型是类对象,则需要确保该类具有有效的赋值运算符。


emplace_back是C++11引入的新特性之一,用于在容器的尾部添加新元素。与push_back相比,emplace_back可以直接在容器中构造新元素,而不是通过对象的拷贝或移动构造函数构造新元素,从而提高了性能。

使用emplace_back时,需要在括号中传递构造函数所需的参数,其语法与直接调用构造函数类似,如下所示:

std::vector<int> vec;

// 使用push_back
vec.push_back(1);

// 使用emplace_back
vec.emplace_back(1);

如果需要添加自定义类型的元素,则需要在类中定义对应的构造函数和移动构造函数,以便emplace_back能够正确地构造新元素。例如:

class Person {
public:
    Person(const std::string& name, int age) : name_(name), age_(age) { }
    Person(std::string&& name, int age) : name_(std::move(name)), age_(age) { }
private:
    std::string name_;
    int age_;
};

std::vector<Person> persons;

// 使用push_back
persons.push_back(Person("Alice", 20));

// 使用emplace_back
persons.emplace_back("Alice", 20);

在上面的例子中,定义了两个构造函数,用于构造Person类型的元素。第一个构造函数接受了一个常量引用,第二个构造函数接受了一个右值引用。在使用emplace_back时,可以直接传递参数,使用移动构造函数构造新元素。emplace_back是C++11引入的新特性之一,用于在容器的尾部添加新元素。与push_back相比,emplace_back可以直接在容器中构造新元素,而不是通过对象的拷贝或移动构造函数构造新元素,从而提高了性能。

使用emplace_back时,需要在括号中传递构造函数所需的参数,其语法与直接调用构造函数类似,如下所示:

std::vector<int> vec;

// 使用push_back
vec.push_back(1);

// 使用emplace_back
vec.emplace_back(1);

如果需要添加自定义类型的元素,则需要在类中定义对应的构造函数和移动构造函数,以便emplace_back能够正确地构造新元素。例如:

class Person {
public:
    Person(const std::string& name, int age) : name_(name), age_(age) { }
    Person(std::string&& name, int age) : name_(std::move(name)), age_(age) { }
private:
    std::string name_;
    int age_;
};

std::vector<Person> persons;

// 使用push_back
persons.push_back(Person("Alice", 20));

// 使用emplace_back
persons.emplace_back("Alice", 20);

在上面的例子中,定义了两个构造函数,用于构造Person类型的元素。第一个构造函数接受了一个常量引用,第二个构造函数接受了一个右值引用。在使用emplace_back时,可以直接传递参数,使用移动构造函数构造新元素。

猜你喜欢

转载自blog.csdn.net/qq_54053990/article/details/131070361