【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;
    }
};
相关推荐
AI备案指南-满满40 分钟前
人工智能拟人化互动服务安全自评估报告的评估要点有哪些?
人工智能·算法·安全·机器人·大模型备案·算法备案
土司大王2 小时前
LeetCode hot100——两两交换链表中的节点
算法·leetcode·职场和发展
大熊背3 小时前
树莓派IspPipeline LSC模块原理详解
算法·lsc·isppipeline·mesh lsc
测试19983 小时前
Selenium 无法定位元素的几种解决方案
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
zander2584 小时前
LeetCode 300. 最长递增子序列
算法·leetcode·深度优先
欧叶冲冲冲4 小时前
Python常见数据结构的CRUD(LeetCode高频版速查)
数据结构·python·leetcode
祖力554 小时前
Linux应用软件编程:目录IO与framebuffer
linux·运维·算法·framebuffer·目录io
名字还没想好☜4 小时前
Go 用 slices/maps 标准库泛型函数:告别手写 Contains、Sort、去重(Go 1.21)
开发语言·后端·算法·golang·go
地平线开发者4 小时前
【模型轻量化专题】深度学习模型为什么需要轻量化
算法
圣保罗的大教堂5 小时前
leetcode 3622. 判断整除性 简单
leetcode