LeetCode第380场周赛个人题解

2024-01-14 15:04

本文主要是介绍LeetCode第380场周赛个人题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

100162.最大频率元素计数

原题链接

思路分析

AC代码

100165.找出数组中的美丽下标I

原题链接

思路分析

AC代码

100160. 价值和小于等于 K 的最大数字

原题链接

思路分析

位运算+二分

AC代码

100207.找出数组中的美丽下标II

原题链接

思路分析

AC代码


100162.最大频率元素计数

原题链接

100162. 最大频率元素计数

思路分析

签到题没什么好说的,统计频次,最大频次为ma的话,记录频次为ma的数字个数

AC代码

class Solution {
public:int maxFrequencyElements(vector<int>& nums) {int hash[101]{0} , ma = 0 , ret = 0;for(auto x : nums)  ma = max(ma , ++hash[x]);for(auto x : hash) if(x == ma) ret += ma;return ret;}
};

100165.找出数组中的美丽下标I

原题链接

100165. 找出数组中的美丽下标 I

思路分析

和第四题一模一样,只不过第四题数据范围大,这道题为了省时间直接用python3跑的,没用C++敲KMP,具体题解看第四题

这道题由于数据量小,查一个i查一个j就行

AC代码

class Solution:def beautifulIndices(self, s: str, a: str, b: str, k: int) -> List[int]:idx = 0ret = []while idx < len(s):i = s.find(a , idx)if i == -1:breakj = s.find(b , i - k if i >= k else 0)if j != -1 and abs(j - i) <= k:ret.append(i)idx = i + 1return sorted(ret)

100160. 价值和小于等于 K 的最大数字

原题链接

 100160. 价值和小于等于 K 的最大数字

思路分析

位运算+二分

写题解的时候瞄了眼力扣题解区那边一堆数位DP+二分的,其实个人感觉用不上数位DP其实就是一个位运算的小tip。

比赛的时候看到题目首先能想到二分,那么问题就落在了二分的可行性判断上。

对于给定一个数字num,如何求出1 到 num的价值和?

其实很容易算的,如果给你一个数字x,问你1到x有多少偶数,想都不用想是x / 2向下取整

如果是奇数,那就是x / 2 + (x & 1)

那么扩展为1到x有多少第i位(i从低到高)为1的数字呢?

假设mask = (1 << (i - 1)),注意1左移i - 1位得到的才是第i位为1

那么  sumi= (x / (mask << 1)) * mask + ((mask & x) ? ((x & (mask - 1)) + 1) : 0)

逐步分析下这个方程什么意思:

加号右边:如果第i位为0,那就不说了,第i位为1假设从最高位到第0位为:xxxxx1xxxxx,那么

从xxxxx100000 ~ xxxxx1xxxxx都是第i位为1,且都不超过x

加号左边:0到x包含了 00000 1 00000~00000 1 11111、00001 1 00000 ~ 00001 1 11111……

其实就是算比第i位高的位的贡献,一个位贡献了1 << i

那么我们可以在O(1)内计算出给定范围内i位为1的数字数目,继而能在O(C)内算出每一位为1的数字数目,其中C为x的位数

那么二分的check函数就能写出来了,二分跑一下即可

AC代码

class Solution {
public:typedef long long ll;const ll maxn = 1e15;bool check(ll x, ll k, ll y){ll s = 0, mask = (1LL << (y - 1));while (mask <= x) {s += (x / (mask << 1)) * mask + ((mask & x) ? ((x & (mask - 1)) + 1) : 0);mask <<= y;}return s <= k;}long long findMaximumNumber(long long k, int x) {ll l = 0, r = maxn , ans = 0;while (l < r){ll mid = (l + r) >> 1;if (check(mid, k, x))ans = mid , l = mid + 1;elser = mid;}return ans;}
};

100207.找出数组中的美丽下标II

原题链接

100207. 找出数组中的美丽下标 II

思路分析

我们通过KMP可以O(n)求出s中所有子串a的下标,也可以求出所有子串b的下标

(就是KMP常用操作,把子串后面添加一个非法字符,这样next数组就变成长度为模式串的了,匹配到一个模式串,模式串就回退就行)

假如我们数组idxa存了子串a的下标,idxb存了子串b的下标

对于idxa中每一个i,我们都在idxb去二分查找一个在i上下浮动k范围内的j,然后记录即可

这样甚至不用排序了还

整体而言这道题比上一道简单,因为上一道check函数细节很容易错

就是KMP板子题

AC代码

void get_nextval(const string& src, vector<int>& nextval)
{int j = 0, k = -1;nextval[0] = -1;while (j < (int)src.size() - 1){if (k == -1 || src[j] == src[k]){j++; k++;if (src[j] != src[k])nextval[j] = k;elsenextval[j] = nextval[k];}else{k = nextval[k];}}
}int index_KMP(vector<int>& idx , vector<int>& next, const string& dst, const string& src, int pos = 0)
{int i = pos, j = 0;while (i < (int)dst.size() && j < (int)src.size()){if (j == -1 || dst[i] == src[j]){i++; j++;if(j == (int)src.size())idx.emplace_back(i - j) , j = next[j];}else{j = next[j];}}if (j == (int)src.size())return i - j;elsereturn -1;
}
class Solution {
public:Solution(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);}vector<int> beautifulIndices(const string& s, const string& a, const string& b, int k) {int n = s.size();vector<int> ret, idxa, idxb;string aa(a + "#") , bb(b + "#");vector<int> nxt1(a.size() + 1), nxt2(b.size() + 1);get_nextval(aa, nxt1), get_nextval(bb, nxt2);;index_KMP(idxa , nxt1, s, a, 0);index_KMP(idxb , nxt2, s, b, 0);if (idxa.empty() || idxb.empty()) return {};for (auto x : idxa){auto it = lower_bound(idxb.begin(), idxb.end(), x >= k ? x - k : 0);if (it == idxb.end()) continue;if (abs(x - *it) <= k) ret.emplace_back(x);}return ret;}
};

这篇关于LeetCode第380场周赛个人题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/605567

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

HomeBank:开源免费的个人财务管理软件

在个人财务管理领域,找到一个既免费又开源的解决方案并非易事。HomeBank&nbsp;正是这样一个项目,它不仅提供了强大的功能,还拥有一个活跃的社区,不断推动其发展和完善。 开源免费:HomeBank 是一个完全开源的项目,用户可以自由地使用、修改和分发。用户友好的界面:提供直观的图形用户界面,使得非技术用户也能轻松上手。数据导入支持:支持从 Quicken、Microsoft Money

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

分布式系统的个人理解小结

分布式系统:分的微小服务,以小而独立的业务为单位,形成子系统。 然后分布式系统中需要有统一的调用,形成大的聚合服务。 同时,微服务群,需要有交流(通讯,注册中心,同步,异步),有管理(监控,调度)。 对外服务,需要有控制的对外开发,安全网关。