【LeetCode周赛】第 385 场周赛

目录

  • [3042. 统计前后缀下标对 I 简单](#3042. 统计前后缀下标对 I 简单)
  • [3043. 最长公共前缀的长度 中等](#3043. 最长公共前缀的长度 中等)
  • [3044. 出现频率最高的质数 中等](#3044. 出现频率最高的质数 中等)
  • [3045. 统计前后缀下标对 II 困难](#3045. 统计前后缀下标对 II 困难)

3042. 统计前后缀下标对 I 简单

3042. 统计前后缀下标对 I

分析:

数据量较少,直接暴力即可,也可以采用 构建前后缀字典树(3045. 统计前后缀下标对 II)。
代码:

cpp 复制代码
class Solution {
public:
    int countPrefixSuffixPairs(vector<string>& words) {
        int n=words.size(), ans=0;
        for(int i=0;i<n;i++){
            int l = words[i].length();
            for(int j=i+1;j<n;j++){
                int le = words[j].length();
                if(l>le) continue;
                if(words[i]==words[j].substr(0,l) && words[i]==words[j].substr(le-l,l)) ans++;
            }
        }
        return ans;
    }
};

3043. 最长公共前缀的长度 中等

3043. 最长公共前缀的长度

分析:

arr1 构建字典树,在遍历 arr2 进行比较即可。
代码:

cpp 复制代码
class Node{
public:
    int val;
    vector<Node*> ne;
    Node() : val(0), ne(10, nullptr) {}
    Node(int v) : val(v), ne(10, nullptr) {}
};

class Solution {
public:
    void buildTree(Node* root, string& s, int i){
        if(i>= s.length()) return;
        int k = s[i] - '0';
        if(root->ne[k] == nullptr){
            Node *node = new Node(s[i]-'0');
            root->ne[k] = node;
        }
        
        buildTree(root->ne[k], s, i+1);
    }

    int longestCommonPrefix(vector<int>& arr1, vector<int>& arr2) {
        Node* root = new Node();
        for(int& a : arr1){
            string s = to_string(a);
            buildTree(root, s, 0);
        }
        int ans=0;
        for(int& a : arr2){
            string s = to_string(a);
            int i=0;
            Node* p=root;
            for(;i<s.length();i++){
                int k = s[i]-'0';
                if(p->ne[k]==nullptr) break;
                p=p->ne[k];
            }
            ans=max(i,ans);
        }
        return ans;
    }
};

3044. 出现频率最高的质数 中等

3044. 出现频率最高的质数

分析:

选择合适的判断质数的算法,按照题意模拟即可。

注意: 如果对数据范围内的质数进行打表,需要注意调用方式,否则会出现多次计算,最终超时。

代码:

对质数打表,再判断。

cpp 复制代码
const int ma = 1e7+5;
vector<int> prime(ma,1);

void getPrimes(){
    prime[0]=prime[1]=0;
    for(int i=2;i<ma;i++){
        if(prime[i]==0) continue;
        for(int j=2;j*i<ma;j++) prime[j*i]=0;
    }
    for(int i=2;i<10;i++) prime[i]=0;
}

void init(){
    static bool ini = false;
    if(!ini){
        ini = true;
        getPrimes();
    }
}

class Solution {
public:

    int mostFrequentPrime(vector<vector<int>>& mat) {
        init();
        int n=mat.size(), m=mat[0].size(), ans=-1, mm=0;
        unordered_map<int,int> mp;
        int move_x[] = {0,1,1,1,0,-1,-1,-1}, move_y[] = {1,1,0,-1,-1,-1,0,1};
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                for(int k=0;k<8;k++){
                    int x=i,y=j;
                    int m_x=move_x[k], m_y=move_y[k], t=mat[i][j];
                    x+=m_x;y+=m_y;
                    while(x>=0&&y>=0&&x<n&&y<m){
                        t=t*10+mat[x][y];
                        if(prime[t]){
                            mp[t]++;
                            if(mm<mp[t]){
                                ans=t;
                                mm=mp[t];
                            }else if(mm==mp[t]){
                                ans=max(ans,t);
                            }
                        }
                        x+=m_x;y+=m_y;
                    }
                }
            }
        }
        return ans;
    }
};

对每一个出现的数进行质数的判断。

cpp 复制代码
class Solution {
public:
    bool isPrime(int n){
        if(n<10) return false;
        for(int i=2;i*i<=n;i++){
            if(n%i==0) return false;
        }
        return true;
    }

    int mostFrequentPrime(vector<vector<int>>& mat) {
        int n=mat.size(), m=mat[0].size(), ans=-1, mm=0;
        unordered_map<int,int> mp;
        int move_x[] = {0,1,1,1,0,-1,-1,-1}, move_y[] = {1,1,0,-1,-1,-1,0,1};
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                for(int k=0;k<8;k++){
                    int x=i,y=j;
                    int m_x=move_x[k], m_y=move_y[k], t=mat[i][j];
                    x+=m_x;y+=m_y;
                    while(x>=0&&y>=0&&x<n&&y<m){
                        t=t*10+mat[x][y];
                        if(isPrime(t)){
                            mp[t]++;
                            if(mm<mp[t]){
                                ans=t;
                                mm=mp[t];
                            }else if(mm==mp[t]){
                                ans=max(ans,t);
                            }
                        }
                        x+=m_x;y+=m_y;
                    }
                }
            }
        }
        return ans;
    }
};

3045. 统计前后缀下标对 II 困难

3045. 统计前后缀下标对 II

分析:

对于前缀,可以通过构建 字典树Trie ,进行判断。

而后缀,观察字符串 S = "abcabc"s1 = "abc"的前后缀情况:

S的前后缀与s1一致,即S[0...2]S[3...5] 均与s1相等。

  • S[0], S[5] = a, c , s1[0], s1[2] = a, c
  • S[1], S[4] = b, b , s1[1], s1[1] = b, b
  • S[2], S[3] = c, a , s1[2], s1[0] = c, a

易得若S(长度为L)的前后缀与s1(长度为l)完全一致则有:

  • S[0], S[L-1] == s1[0], s1[l-1]
  • S[1], S[L-2] == s1[1], s1[l-2]
  • ...
  • S[l-1], S[L-l+1] == s1[l-1], s1[0]

根据得到的性质,在构建字典树时,同时记录前缀与后缀的字符,再进行对比即可。

注意: i < j,因此不需要根据字符串长度进行排序。

也可以正常构建字典树来对比前缀,同时使用 **Z函数(拓展KMP)**来对比后缀。

代码:

cpp 复制代码
struct Node {
    unordered_map<int, Node*> son;
    int cnt=0;
};

class Solution {
public:
    long long countPrefixSuffixPairs(vector<string>& words) {
        long long ans=0;
        Node *root = new Node();
        for(string& s : words){
            int n = s.length();
            Node *cur = root;
            for(int i=0;i<n;i++){
                int p = (int) ((s[i] - 'a') << 5) | (s[n - i - 1] - 'a'); // 仅26个字母,五位二进制即可完全表示,使用十位二进制数来表示(前五位表示前缀,后五位表示后缀)
                if(cur->son[p] == nullptr){
                    cur->son[p] = new Node();
                }
                cur = cur->son[p];
                ans += cur->cnt;
            }
            cur->cnt++;
        }
        return ans;
    }
};
相关推荐
Amor风信子几秒前
【力扣】2376. 统计特殊整数
算法·leetcode·职场和发展
极客小张1 分钟前
基于正点原子Linux开发板的智能监控与家电控制系统设计:深度解析Video4Linux和TCP/IP技术栈
linux·运维·c++·物联网·网络协议·tcp/ip·算法
JustCouvrir1 小时前
代码随想录算法训练营Day5
算法
周哈里窗的编程2 小时前
CSP-CCF★201912-2回收站选址★
c++·算法·图论
SpongeG3 小时前
数据结构第三周做题总结_链表
数据结构·算法·链表
everyStudy3 小时前
前端五种排序
前端·算法·排序算法
little redcap5 小时前
第十九次CCF计算机软件能力认证-乔乔和牛牛逛超市
数据结构·c++·算法
muyierfly6 小时前
34.贪心算法1
算法·贪心算法
luthane8 小时前
python 实现average mean平均数算法
开发语言·python·算法
静心问道8 小时前
WGAN算法
深度学习·算法·机器学习