统计最大组的数目
题意简述
给定一个正整数 。将 至 的整数按 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 个回文字符串
题意简述
给定一个包含小写字母的可重集合 ,求是否能恰好完全使用这些所有的小写字母构造 个回文串。
恰好完全使用形式化的定义为:对于每个小写字母,都有,其在给定可重集合中出现的次数与其在构造的 个回文串中的总出现次数恰好相同。
关键数据规模:
解法
我们首先尝试利用可重集合 构造最少个数的回文串:
- 通过分析,不难发现,对于所有在 中出现次数为奇数的字母(下简称出现奇数次字母)而言,它们必须在至少一个构造的奇数长度的回文串中作为回文中心出现。因此,构造回文串数目的下界为出现奇数次字母的数量(特别地,当该数量为 时,有下界为 ,这并不对我们接下来的分析和解法造成本质影响)。我们记这个下界为 。
- 稍加思考,不难发现,我们很容易构造达到这个下界 :
- 初始化:令第 ()个回文串为单个第 个出现奇数次字母。此时所有字母的待出现次数均应为偶数。
- 若所有字母的待出现次数均为 ,则构造结束。否则,继续步骤 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)
做菜顺序
题意简述
给定 道菜品和它们的满意程度 (),你可以取其中任意菜品进行任意排列 ,其中 。你的总收益为 。
求最大总收益。
关键数据规模:
解法
很显然,题目中选菜品的操作,与选出若干 是等价的。因此,方便起见,我们首先将 降序排序。
接下来,我们将说明,即一定存在一组最优解,满足如下性质:
- 选出的 一定为降序排序后的一个前缀:即,假设选择了 个 ,则它们恰好为 。
- 很容易使用反证法进行证明:如果存在 被选且 ,则使用任意未被选的 ()替换之,收益一定不会变得更差。
- 很容易使用反证法进行证明:如果存在更靠前的 大于更靠后的 ,则将它们交换,收益一定不会变得更差。
于是,我们假设选取 时,最大收益为 。稍加思考,可发现:
即: 为 前缀和的前缀和。
虽然我们还可以通过推导得知 的前缀和的正负关于其下标是满足非严格单调性的,并进而发现 是单峰的,但这对本题并没有任何帮助。因为所有 的最大值即为答案,通过递推式进行求解即可。
这个算法的时间复杂度是 的,其中的瓶颈为排序,其余部分的时间复杂度为 。
一种使用 Python 语言的较为简短的实现如下:
max(accumulate(accumulate([0] + sorted(satisfaction, reverse = True))))
题解:王聿中
有关LeetCode比赛
LeetCode 每周日上午都会举办一个半小时的比赛,通常会有 4 道题目;在每双周周六晚上还会举办两个半小时的双周赛,通常会有 4 道题目。
无论你是萌新还是大佬,只要你爱好编程与算法,在这里都能找到适合你的位置。
如果你有意参加技术面试,这种模拟考试的机会也是十分珍贵的!
我们建立了QQ群,每次比赛后我们会分享参考解法并接受答疑,欢迎讨论!