leetcode最大矩形_LeetCode 第 23 场双周赛 题解

统计最大组的数目

题意简述

给定一个正整数 。将 至 的整数按 10 进制下数位和进行分组,并求包含元素并列最多的组的数目。

关键数据规模:

解法

本题只需按题目要求进行统计即可。最优时间复杂度为 ,更差时间复杂度的算法也可以通过本题。

一种使用 Python 语言的较为简短的实现如下:

s=list(map(lambda s:sum(map(int,s)),map(str,range(1,n+1))))
arr=[s.count(x) for x in range(40)]
return arr.count(max(arr))

构造 K 个回文字符串

题意简述

给定一个包含小写字母的可重集合 ,求是否能恰好完全使用这些所有的小写字母构造 个回文串。

恰好完全使用形式化的定义为:对于每个小写字母,都有,其在给定可重集合中出现的次数其在构造的 个回文串中的总出现次数恰好相同。

关键数据规模:

解法

我们首先尝试利用可重集合 构造最少个数的回文串:

  • 通过分析,不难发现,对于所有在 中出现次数为奇数的字母(下简称出现奇数次字母)而言,它们必须在至少一个构造的奇数长度的回文串中作为回文中心出现。因此,构造回文串数目的下界为出现奇数次字母的数量(特别地,当该数量为 时,有下界为 ,这并不对我们接下来的分析和解法造成本质影响)。我们记这个下界为 。
  • 稍加思考,不难发现,我们很容易构造达到这个下界 :
  1. 初始化:令第 ()个回文串为单个第 个出现奇数次字母。此时所有字母的待出现次数均应为偶数。
  2. 若所有字母的待出现次数均为 ,则构造结束。否则,继续步骤 3。
  3. 任选一个待出现次数不为 的字母,将两个该字母分别置于第 个构造回文串的首、位。这个操作不会破坏所有字母待出现次数均为偶数的性质,因此选到的字母待出现次数不为 ,操作一定可以完成。完成后,返回步骤 2 进行判断。

在此基础上,我们将通过归纳法,来证明对于任意大于 、小于 的构造串个数,都有合法的构造。

  • 基础:存在包含 个回文串的合法构造。
  • 归纳:对于任意 且 ,由归纳假设,任取一包含 个回文串的合法构造:由鸽巢原理可知,其中一定存在长度超过 的串。任取其中一个,若其长度超过 ,则删除其首、尾字符(这两个字符一定是相同的,不妨假设为 a),并添加一个新的回文串 aa;若其长度恰好为 ,则将其拆分为两个长度为 的回文串。至此,得到一个包含 个回文串的合法构造。

于是,求出 ,并判断 是否成立即可。

一种使用 Python 语言的较为简短的实现如下:

return k>=sum(map(lambda x:x%2,[s.count(chr(97+i)) for i in range(26)])) and k<=len(s)

圆和矩形是否有重叠

题意简述

在一个二维平面上,以圆心坐标、半径的形式给定一个圆;同时以左下角、右上角坐标的形式给定一个与坐标轴平行的矩形。求矩形和圆是否有重叠部分。

解法

简单地考虑,分类讨论即可。即,若存在重叠部分,则必有下面的其中之一:

  • 矩形的顶点在圆内
  • 矩形的边与圆相交
  • 矩形包含圆
  • 圆包含矩形

厉害的解法

这里有一个厉害的解法,这个解法的实现也非常简短,以 Python 为例:

xm,ym = (x1+x2)/2,(y1+y2)/2 # center of rectangle
x0,y0 = abs(xm-x_center),abs(ym-y_center) # vector from center of rectangle to circle
xu,yu = max(x0-(x2-xm),0),max(y0-(y2-ym),0) # vector: point which is in rectangle and the nearest to center of circle -> center of circle
return xu**2+yu**2<=radius**2

代码转载信息:

作者:mbinary 链接:https://leetcode-cn.com/problems/circle-and-rectangle-overlapping/solution/zui-you-fang-fa-by-mbinary/ 来源:力扣(LeetCode)

做菜顺序

题意简述

给定 道菜品和它们的满意程度 (),你可以取其中任意菜品进行任意排列 ,其中 。你的总收益为 。

求最大总收益。

关键数据规模:

解法

很显然,题目中选菜品的操作,与选出若干 是等价的。因此,方便起见,我们首先将 降序排序。

接下来,我们将说明,即一定存在一组最优解,满足如下性质:

  1. 选出的 一定为降序排序后的一个前缀:即,假设选择了 个 ,则它们恰好为 。
  • 很容易使用反证法进行证明:如果存在 被选且 ,则使用任意未被选的 ()替换之,收益一定不会变得更差。
选出 后,它们的排列顺序一定为 。
  • 很容易使用反证法进行证明:如果存在更靠前的 大于更靠后的 ,则将它们交换,收益一定不会变得更差。

于是,我们假设选取 时,最大收益为 。稍加思考,可发现:

即: 为 前缀和的前缀和。

虽然我们还可以通过推导得知 的前缀和的正负关于其下标是满足非严格单调性的,并进而发现 是单峰的,但这对本题并没有任何帮助。因为所有 的最大值即为答案,通过递推式进行求解即可。

这个算法的时间复杂度是 的,其中的瓶颈为排序,其余部分的时间复杂度为 。

一种使用 Python 语言的较为简短的实现如下:

max(accumulate(accumulate([0] + sorted(satisfaction, reverse = True))))

题解:王聿中

有关LeetCode比赛

  LeetCode 每周日上午都会举办一个半小时的比赛,通常会有 4 道题目;在每双周周六晚上还会举办两个半小时的双周赛,通常会有 4 道题目。

  无论你是萌新还是大佬,只要你爱好编程与算法,在这里都能找到适合你的位置。

  如果你有意参加技术面试,这种模拟考试的机会也是十分珍贵的!

3d13866ca5d238bbf5052e24fa6b280c.png

  我们建立了QQ群,每次比赛后我们会分享参考解法并接受答疑,欢迎讨论

ce106761def9ffc0625dbd58143efc5a.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值