LeetCode 第385场周赛个人题解

这篇具有很好参考价值的文章主要介绍了LeetCode 第385场周赛个人题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

100212. 统计前后缀下标对 I

原题链接

题目描述

接口描述

思路分析

代码详解

100229. 最长公共前缀的长度

原题链接

题目描述

接口描述

思路分析

代码详解

100217. 出现频率最高的素数

原题链接

题目描述

接口描述

思路分析

代码详解

100212. 统计前后缀下标对 II

原题链接

题目描述

接口描述

思路分析

代码详解


100212. 统计前后缀下标对 I

原题链接

100212. 统计前后缀下标对 I

题目描述

给你一个下标从 0 开始的字符串数组 words 。

定义一个 布尔 函数 isPrefixAndSuffix ,它接受两个字符串参数 str1 和 str2 :

  • 当 str1 同时是 str2 的前缀(

    prefix

    )和后缀(

    suffix

    )时,isPrefixAndSuffix(str1, str2) 返回 true,否则返回 false

例如,isPrefixAndSuffix("aba", "ababa") 返回 true,因为 "aba" 既是 "ababa" 的前缀,也是 "ababa" 的后缀,但是 isPrefixAndSuffix("abc", "abcd") 返回 false

以整数形式,返回满足 i < j 且 isPrefixAndSuffix(words[i], words[j]) 为 true 的下标对 (i, j) 的 数量 

示例 1:

输入:words = ["a","aba","ababa","aa"]
输出:4
解释:在本示例中,计数的下标对包括:
i = 0 且 j = 1 ,因为 isPrefixAndSuffix("a", "aba") 为 true 。
i = 0 且 j = 2 ,因为 isPrefixAndSuffix("a", "ababa") 为 true 。
i = 0 且 j = 3 ,因为 isPrefixAndSuffix("a", "aa") 为 true 。
i = 1 且 j = 2 ,因为 isPrefixAndSuffix("aba", "ababa") 为 true 。
因此,答案是 4 。

示例 2:

输入:words = ["pa","papa","ma","mama"]
输出:2
解释:在本示例中,计数的下标对包括:
i = 0 且 j = 1 ,因为 isPrefixAndSuffix("pa", "papa") 为 true 。
i = 2 且 j = 3 ,因为 isPrefixAndSuffix("ma", "mama") 为 true 。
因此,答案是 2 。

示例 3:

输入:words = ["abab","ab"]
输出:0
解释:在本示例中,唯一有效的下标对是 i = 0 且 j = 1 ,但是 isPrefixAndSuffix("abab", "ab") 为 false 。
因此,答案是 0 。

接口描述

class Solution {
public:
    int countPrefixSuffixPairs(vector<string>& words) {
        
    }
};

思路分析

前后缀问题很容易想到字符串哈希和字典树

这里使用字典树解法

  1. 遍历字符串数组,用kmp的next数组推导方式计算出所有公共前后缀,并插入到哈希表中
  2. 倒序遍历,在字典树上匹配,如果匹配长度在哈希表中存在,我们就加上这个字典树节点处的权值
  3. 结束后倒序插入当前字符串

时间复杂度O(Σlen(s))

代码详解

class Solution
{
public:
    struct node
    {
        int cnt = 0;
        unordered_map<char, node *> ch;
    } *root, *t;
    bool isloop(const string &s)
    {
        int l = 0, r = (int)s.size() - 2;
        while (l < r)
            if (s[l] != s[r])
                return false;
            else
                l++, r--;
        return true;
    }
    long long countPrefixSuffixPairs(vector<string> &words)
    {
        long long ret = 0;
        root = new node;
        for (auto &s : words)
        {
            int n = s.size();
            vector<int> nxt(n + 1, -1);
            s.push_back('#');
            int j = 0, k = -1;
            unordered_set<int> mp;
            while (j < n)
            {
                if (k == -1 || s[j] == s[k])
                {
                    k++, j++;
                    nxt[j] = k;
                }
                else
                    k = nxt[k];
            }
            while (j)
                mp.insert(nxt[j]), j = nxt[j];

                mp.insert(n);
            t = root;
            for (int i = n - 1; i >= 0; i--)
            {
                if (!t->ch.count(s[i]))
                    break;
                t = t->ch[s[i]];
                if (mp.count(n - i))
                    ret += t->cnt;
            }
            t = root;
            for (int i = n - 1; i >= 0; i--)
            {
                if (!t->ch.count(s[i]))
                    t->ch[s[i]] = new node;
                t = t->ch[s[i]];
            }
            t->cnt++;
        }
        return ret;
    }
};

100229. 最长公共前缀的长度

  

原题链接

  100229. 最长公共前缀的长度

题目描述

  

给你两个 正整数 数组 arr1 和 arr2 。

正整数的 前缀 是其 最左边 的一位或多位数字组成的整数。例如,123 是整数 12345 的前缀,而 234 不是 

设若整数 c 是整数 a 和 b 的 公共前缀 ,那么 c 需要同时是 a 和 b 的前缀。例如,5655359 和 56554 有公共前缀 565 ,而 1223 和 43456 没有 公共前缀。

你需要找出属于 arr1 的整数 x 和属于 arr2 的整数 y 组成的所有数对 (x, y) 之中最长的公共前缀的长度。

返回所有数对之中最长公共前缀的长度。如果它们之间不存在公共前缀,则返回 0 。

示例 1:

输入:arr1 = [1,10,100], arr2 = [1000]
输出:3
解释:存在 3 个数对 (arr1[i], arr2[j]) :
- (1, 1000) 的最长公共前缀是 1 。
- (10, 1000) 的最长公共前缀是 10 。
- (100, 1000) 的最长公共前缀是 100 。
最长的公共前缀是 100 ,长度为 3 。

示例 2:

输入:arr1 = [1,2,3], arr2 = [4,4,4]
输出:0
解释:任何数对 (arr1[i], arr2[j]) 之中都不存在公共前缀,因此返回 0 。
请注意,同一个数组内元素之间的公共前缀不在考虑范围内。

接口描述

  

class Solution {
public:
    int longestCommonPrefix(vector<int>& arr1, vector<int>& arr2) {
        
    }
};

思路分析

  还是字典树

  1. 把arr1中所有数字转化为字符串插入到字典树中
  2. 遍历arr2,在字典树上进行匹配,维护最长前缀长度

代码详解

class Solution
{
public:
    struct node
    {
        unordered_map<char, node *> ch;
    } *root;
    int longestCommonPrefix(vector<int> &arr1, vector<int> &arr2)
    {
        root = new node;
        int ret = 0;
        for (auto v : arr1)
        {
            node *t = root;
            for (auto x : to_string(v))
            {
                if (!t->ch.count(x))
                    t->ch[x] = new node;
                t = t->ch[x];
            }
        }
        for (auto &v : arr2)
        {
            node *t = root;
            int s = 0;
            for (auto x : to_string(v))
            {
                if (!t->ch.count(x))
                    break;
                t = t->ch[x];
                s++;
            }
            ret = max(ret, s);
        }
        return ret;
    }
};

100217. 出现频率最高的素数

  

原题链接

  100217. 出现频率最高的素数

题目描述

  

给你一个大小为 m x n 、下标从 0 开始的二维矩阵 mat 。在每个单元格,你可以按以下方式生成数字:

  • 最多有 8 条路径可以选择:东,东南,南,西南,西,西北,北,东北。
  • 选择其中一条路径,沿着这个方向移动,并且将路径上的数字添加到正在形成的数字后面。
  • 注意,每一步都会生成数字,例如,如果路径上的数字是 1, 9, 1,那么在这个方向上会生成三个数字:1, 19, 191 。

返回在遍历矩阵所创建的所有数字中,出现频率最高的、大于 10

素数

;如果不存在这样的素数,则返回  -1  。如果存在多个出现频率最高的素数,那么返回其中最大的那个。

注意:移动过程中不允许改变方向。

接口描述

  

class Solution {
public:
    int mostFrequentPrime(vector<vector<int>>& mat) {
        
    }
};

思路分析

  素数筛+暴力模拟

预处理素数筛,遍历每个网格的八个方向维护出现的大于10的素数的次数即可

代码详解

const int maxn = 1e7 + 10;
bitset<maxn + 1> prime; // 0为素数 1为合数
int primes[maxn + 1], cnt;
bool f = 0;
inline void calcprime(int x)
{
    prime[2] = 0;
    for (int i = 2; i <= x; i++)
    {
        if (!prime[i])
            primes[cnt++] = i;
        for (int j = 0; j < cnt && primes[j] * i <= x; j++)
        {
            prime[primes[j] * i] = 1;
            if (i % primes[j] == 0)
                break;
        }
    }
}
class Solution
{
public:
    Solution()
    {
        if (!f)
            calcprime(1e7), f = 1;
        ;
    }
    static constexpr int dir[9] = {1, 0, -1, 0, 1, 1, -1, -1, 1};
    int mostFrequentPrime(vector<vector<int>> &mat)
    {
        int m = mat.size(), n = mat[0].size(), ret = -1, ma = 0;
        int cnt[10000005]{0};
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                for (int k = 0, x, y; k < 8; k++)
                {
                    int s = 0;
                    x = i, y = j;
                    while (x >= 0 && x < m && y >= 0 && y < n)
                    {
                        s = (s << 3) + (s << 1) + mat[x][y];
                        if (s > 10 && !prime[s])
                        {
                            ++cnt[s];
                            if (cnt[s] > ma)
                                ma = cnt[s], ret = s;
                            else if (cnt[s] == ma)
                                ret = max(ret, s);
                        }
                        x += dir[k], y += dir[k + 1];
                    }
                }
            }
        }
        return ret;
    }
};

100212. 统计前后缀下标对 II

  

原题链接

  100208. 统计前后缀下标对 II

题目描述

  

给你一个下标从 0 开始的字符串数组 words 。

定义一个 布尔 函数 isPrefixAndSuffix ,它接受两个字符串参数 str1 和 str2 :

  • 当 str1 同时是 str2 的前缀(

    prefix

    )和后缀(

    suffix

    )时,isPrefixAndSuffix(str1, str2) 返回 true,否则返回 false

例如,isPrefixAndSuffix("aba", "ababa") 返回 true,因为 "aba" 既是 "ababa" 的前缀,也是 "ababa" 的后缀,但是 isPrefixAndSuffix("abc", "abcd") 返回 false

以整数形式,返回满足 i < j 且 isPrefixAndSuffix(words[i], words[j]) 为 true 的下标对 (i, j) 的 数量 

接口描述

  

class Solution {
public:
    long long countPrefixSuffixPairs(vector<string>& words) {
        
    }
};

思路分析

  思路同第一题文章来源地址https://www.toymoban.com/news/detail-826821.html

代码详解

class Solution
{
public:
    struct node
    {
        int cnt = 0;
        unordered_map<char, node *> ch;
    } *root, *t;
    bool isloop(const string &s)
    {
        int l = 0, r = (int)s.size() - 2;
        while (l < r)
            if (s[l] != s[r])
                return false;
            else
                l++, r--;
        return true;
    }
    long long countPrefixSuffixPairs(vector<string> &words)
    {
        long long ret = 0;
        root = new node;
        for (auto &s : words)
        {
            int n = s.size();
            vector<int> nxt(n + 1, -1);
            s.push_back('#');
            int j = 0, k = -1;
            unordered_set<int> mp;
            while (j < n)
            {
                if (k == -1 || s[j] == s[k])
                {
                    k++, j++;
                    nxt[j] = k;
                }
                else
                    k = nxt[k];
            }
            while (j)
                mp.insert(nxt[j]), j = nxt[j];

                mp.insert(n);
            t = root;
            for (int i = n - 1; i >= 0; i--)
            {
                if (!t->ch.count(s[i]))
                    break;
                t = t->ch[s[i]];
                if (mp.count(n - i))
                    ret += t->cnt;
            }
            t = root;
            for (int i = n - 1; i >= 0; i--)
            {
                if (!t->ch.count(s[i]))
                    t->ch[s[i]] = new node;
                t = t->ch[s[i]];
            }
            t->cnt++;
        }
        return ret;
    }
};

到了这里,关于LeetCode 第385场周赛个人题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【LeetCode周赛】LeetCode第370场周赛

    一场比赛中共有 n 支队伍,按从 0 到 n - 1 编号。 给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 = i, j = n - 1 且 i != j 的所有 i, j :如果 grid[i][j] == 1,那么 i 队比 j 队 强 ;否则,j 队比 i 队 强 。 在这场比赛中,如果不存在某支强于 a 队的队伍,则认为

    2024年02月05日
    浏览(37)
  • 【LeetCode周赛】LeetCode第358场周赛

    给你一个下标从0开始的整数数组nums。请你从nums中找出和最大的一对数,且这两个数数位上最大的数字相等。 返回最大和,如果不存在满足题意的数字对,返回 -1 。 示例 1: 输入:nums = [51,71,17,24,42] 输出:88 解释: i = 1 和 j = 2 ,nums[i] 和 nums[j] 数位上最大的数字相等,且这

    2024年02月12日
    浏览(28)
  • 【LeetCode周赛】LeetCode第359场周赛

    给你一个字符串数组 words 和一个字符串 s ,请你判断 s 是不是 words 的 首字母缩略词 。 如果可以按顺序串联 words 中每个字符串的第一个字符形成字符串 s ,则认为 s 是 words 的首字母缩略词。例如,“ab” 可以由 [“apple”, “banana”] 形成,但是无法从 [“bear”, “aardvark”

    2024年02月10日
    浏览(33)
  • LeetCode第347场周赛

    2023.5.28LeetCode第347场周赛 从最后一位开始遍历,为0则跳过 暴力模拟 对于每个 s[i] != s[i - 1] ,要使其相等 有两种选择,翻转前 i 个,或者翻转后 n - i 个,选择代价最小的方案 动态规划 从小到大枚举所有值,每个值一定是从更小的数转移而来 定义动态规划数组f, f[i][j] 表示

    2024年02月06日
    浏览(65)
  • LeetCode第343场周赛

    2023.4.30LeetCode第343场周赛 根据题意模拟 使用哈希表记录每个数出现的位置,再用m+n个集合记录每一行和每一列被涂满的格子数,若某行或某列全部被涂满则返回答案 BFS 首先将距离大于两点的曼哈顿距离的特殊路径去掉 每个点考虑经过每个特殊路径到达,分成两段,一段是当

    2024年02月02日
    浏览(29)
  • LeetCode第354场周赛

    给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 对 nums 中的元素 nums[i] 而言,如果 n 能够被 i 整除,即 n % i == 0 ,则认为 num[i] 是一个 特殊元素 。 返回 nums 中所有 特殊元素 的 平方和 。 直接模拟就好了 给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k 。 在一

    2024年02月16日
    浏览(31)
  • leetcode 第360场周赛

    好久没参加leetcode周赛了,比赛时间都从两小时变成了一个半小时。这次周赛由两道签到题和两道中等难度题组成,严格来说最后一道的难度也可以视为hard,但是只要想到正确的思路,编码还是比较容易的。 比赛链接:leetcode 第 360 场周赛 题目描述 给你一个长度为 n 的字符串

    2024年02月11日
    浏览(28)
  • [LeetCode周赛复盘] 第 359 场周赛20230820

    T1 模拟。 T2 数学贪心。 T3 dp。 T4 分组+滑窗。 2828. 判别首字母缩略词 1. 题目描述 2. 思路分析 按题意模拟即可。 3. 代码实现 2829. k-avoiding 数组的最小总和 1. 题目描述 2. 思路分析 贪心 1~k-1中,选了1就不能选k-1;选了2就不能选k-2… 因此可以选1~k//2 剩余的从k开始向上选。 可以

    2024年02月11日
    浏览(28)
  • [LeetCode周赛复盘] 第 353 场周赛20230709

    感觉有奖品大家都来了。 T1 数学。 T2 dp。 T3 dp。 T4 差分/BIT RUPQ。 6451. 找出最大的可达成数字 1. 题目描述 2. 思路分析 为了使x num在t步内相同,需要相向而行,每步最大缩短距离是2,那么t步距离是2t。 3. 代码实现 6899. 达到末尾下标所需的最大跳跃次数 1. 题目描述 2. 思路分

    2024年02月15日
    浏览(21)
  • [LeetCode周赛复盘] 第 348场周赛20230604

    这场可惜了。 T1 模拟。 T2 模拟。 T3 倒序计算。 T4 同时限制上下界的数位DP。 6462. 最小化字符串长度 1. 题目描述 2. 思路分析 题意仔细想一下就会发现,其实会将每个字符仅留1个。 3. 代码实现 6424. 半有序排列 1. 题目描述 2. 思路分析 由于只能相邻交换来移动,因此每次只能

    2024年02月08日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包