7. Reverse Integer
倒置一个整数, 此答案忽略了原题中的范围判断。原题
1 | Input: -123 |
方法一:str
1 | def reverse_int(x): |
方法二:math
1 | def reverse(self, x: int) -> int: |
9. Palindrome Number
判断一个数是否是回文数,这里把负数认为是不符合条件的。原题
方法一:str
1 | def is_palindrome(x): |
方法二:math
1 | def is_palindrome(x): |
13. Roman to Integer
罗马数字转换整型。原题
1 | def roman_to_int(s): |
69. Sqrt(x)
实现开方,返回整数部分。原题
1 | Input: 8 |
方法一:二分法。
1 | def mySqrt(self, x: int) -> int: |
1 | def my_sqrt(x): |
367. Valid Perfect Square
判断一个数是不是某个数的平方。原题
1 | Input: 16 |
1 | def isPerfectSquare(self, num): |
171. Excel Sheet Column Number
excel表格列表数字转换,二十六进制。原题
1 | A -> 1 |
1 | def titleToNumber(self, s: str) -> int: |
168. Excel Sheet Column Title
excel转换,数字转字母。十进制->26进制。原题
1 | def convertToTitle(self, n): |
172. Factorial Trailing Zeroes
求n的阶乘末尾有几个0。原题
1 | Input: 5 |
思路:每一对2和5可以产生一个0,在n的阶乘中,5比2多,所以问题变成求5的个数,而25这种数有两个5,所以递归求解
1 | def trailing_zeroes(n): |
204. Count Primes
求小于n的整数中,有多少个质数。原题
1 | def countPrimes(self, n): |
50. Pow(x, n)
实现pow函数。原题
1 | Input: 2.00000, 10 |
说明:常规方法在Leetcode 上内存会爆掉。
1 | class Solution(object): |
233. Number of Digit One
1~n数字中1的个数。原题
1 | def countDigitOne(self, n): |
263. Ugly Number
判断一个数是否是丑数。原题
方法一:根据定义实现。< num
是为了判断num=0
的情况。
1 | def isUgly(self, num): |
264. Ugly Number II
输出第n个丑数。原题
书中的方法
1 | def nthUglyNumber(self, n): |
67.Add Binary
实现二进制加法。原题
1 | Input: a = "11", b = "1" |
方法一:按照加法的二进制思想来计算,不过Runtime大约100ms。后来试着将list comprehension
拆成一个for
循环,也并没有提高速度。居然beats
只有4%,难道大部分人都用的bin
。讨论区简单翻了了一下,没有找到一个高效的pythonic的方法。
1 | def addBinary(self, a, b): |
202. Happy Number
判断是否是欢乐数。进行所有位的平方和运算,最后为1的是欢乐数。原题
1 | Input: 19 |
方法一:思路,使用一个字典映射0~9的平方值,然后如果死循环的话,各位数的和一定存在着一种循环,所以用一个set
来判断是否重复。
1 | def isHappy(self, n): |
231. Power of Two
判断一个数是否是2的n次方。思路也就是判断这个数的二进制形式是否只有一个’1’。原题
方法一:可以用作通用方法。
1 | def isPowerOfTwo(self, n, power=2): |
方法二:二进制统计1。
1 | def isPowerOfTwo(self, n): |
方法三:如果一个数n的二进制只有一个1,那么n&(n-1)
一定为0。
1 | def isPowerOfTwo(self, n): |
342. Power of Four
判断一个数是否是4的n次方。原题
方法一:从简单入手通过231题,了解到了2的n次方特点是,二进制形式只有一个’1’,那么4的n次方就是不但只有一个’1’,后面还跟了偶数个’0’。
1 | def isPowerOfFour(self, num): |
1 | def isPowerOfFour(self, num): |
方法三:也可以使用正则。
1 | def isPowerOfFour(self, num): |
292. Nim Game
说,有这么一堆石头,一次只能拿1~3个,拿到最后一个石头的人获胜。求n堆石头,你先拿是否可以获胜。原题
思路:找规律,发现只有最后剩4个石头的时候,此时轮到谁,谁输。
1 | def canWinNim(self, n): |
400. Nth Digit
找出无限整数序列中的第n个数字。原题
1 | Input: |
思路,根据n的位数,将无限序列分为几个范围。
size of n | step | start | ~ | stop |
---|---|---|---|---|
1 | 9 | 1 | ~ | 9 |
2 | 90 | 10 | ~ | 99 |
3 | 900 | 100 | ~ | 999 |
- 寻找范围。寻找n处于哪个范围,是1~9,还是10~99,例如n=15。则需要跳过1~9的范围,而这个范围有
size*step
个数字,所以问题变成在10~99范围上寻找第15-1*9=6
个数。 - 定位数字。10~99范围中是从10开始的,每一个数都有两位数字,所以最终数字为
10+(6-1)//2
,因为索引从0开始,所以需要-1。 - 定位数字的位。上一步找到了数字为12,对size求余就可以知道,
'12'[(6-1)%2]='2'
。
1 | def findNthDigit(self, n): |
415. Add Stings
给定两个字符串表示的数字,把它们相加,这两个数的长度小于5100,不能使用任何BitIntegr库或是直接将其转换为整数。ps: 题中要求不将输入直接转换成int,所以我个人认为int还是可以使用的,有一些答案中是使用了ord来做运算。原题
方法一:不使用标准库。
1 | def addStrings(self, num1, num2): |
1 | def addStrings(self, num1, num2): |
492. Construct the Rectangle
给定一个面积,求组成这个面积的长高差最小。原题
1 | Input: 4 |
1 | def constructRectangle(self, area): |
方法二:整理一下思路其实很简单,之前想多了还以为有二分的方法。递减肯定是会优先退出循环的,但是我还不知道怎么证明这个结论。
1 | def constructRectangle(self, area): |
504. Base 7
10进制转7进制。原题
1 | Input: 100 |
方法一:需要注意负数。
1 | def convertToBase7(self, num: int) -> str: |
970. Powerful Integers
求满足x^i+y^j <= bound的所有和。原题
1 | Input: x = 2, y = 3, bound = 10 |
方法一:这题难得地方在于两个循环的临界值,貌似我这样写也不是最优解,原题的Solution中给定了2**18>bound的最大值。所以两个范围都是18。
1 | def powerfulIntegers(self, x, y, bound): |
973. K Closest Points to Origin
求离原点最近的K个坐标点。原题
1 | Input: points = [[1,3],[-2,2]], K = 1 |
方法一:很简单。
1 | def kClosest(self, points, K): |
976. Largest Perimeter Triangle
给定一个边长数组,求能组成的三角形的最长周长。原题
方法一:这个也不难,就是长度为3的滑动窗口。
1 | def largestPerimeter(self, A): |
628. Maximum Product of Three Numbers
数组中三个数的最大乘积。元素范围[-1000, 1000]。原题
1 | Input: [1,2,3,4] |
方法一:排序。在正数个数大于等于3的时候,显然最大的三个数就可以产生最大的乘积。而当正数个数不够的时候,那么必须需要两个最小的负数(即绝对值最大),和一个最大的正数。
1 | def maximumProduct(self, nums): |
1 | def maximumProduct(self, nums): |
728. Self Dividing Numbers
自整除数字,一个数字能够被本身的每个数字整除,并且不能有0,求某个范围内所有的数。原题
1 | Input: |
方法一:Brute Force. 此题强行使用列表生成式没有意义。
1 | def selfDividingNumbers(self, left, right): |
836. Rectangle Overlap
矩形是否重叠,矩形的边平行于坐标轴。原题
1 | Input: rec1 = [0,0,2,2], rec2 = [1,1,3,3] |
方法一:通过画图找出的规律。
1 | def isRectangleOverlap(self, rec1: 'List[int]', rec2: 'List[int]') -> 'bool': |
Given 2 segment (left1, right1)
, (left2, right2)
, how can we check whether they overlap?
If these two intervals overlap, it should exist an number x
,
1 | left1 < x < right1 && left2 < x < right2 |
1 | def isRectangleOverlap(self, rec1: 'List[int]', rec2: 'List[int]') -> 'bool': |
991. Broken Calculator
坏掉的计算器,只能*2或者-1,使X变为Y。原题
1 | Input: X = 5, Y = 8 |
解析:如果从X到Y问题会变得复杂,不确定什么时候该*2或者是-1。所以逆向思维从Y变成X。
If
Y <= X
, we won’t doY / 2
anymore.
We will increaseY
until it equals toX
So before that, while
Y > X
, we’ll keep reducingY
, until it’s smaller thanX
.
IfY
is odd, we can do onlyY = Y + 1
IfY
is even, if we plus 1 toY
, thenY
is odd, we need to plus another 1.
And because(Y + 1 + 1) / 2 = (Y / 2) + 1
, 3 operations are more than 2.
We always chooseY / 2
ifY
is even.
方法一:iteratively.
1 | def brokenCalc(self, X: 'int', Y: 'int') -> 'int': |
方法二:方法一变形。因为如果Y是奇数,那么必定在+1操作后要/2,这里将其合并
1 | def brokenCalc(self, X: 'int', Y: 'int') -> 'int': |
ans += (Y&1) + 1
表示,而Y
在是奇数时先+1再//2即Y = (Y + 1) // 2
,偶数时Y = Y // 2
,其实,对于偶数来说Y=(Y+1)//2
和Y=Y//2
结果一样。所以可以写成。
1 | def brokenCalc(self, X: 'int', Y: 'int') -> 'int': |
Y&1
必须括号
1 | def brokenCalc(self, X: 'int', Y: 'int') -> 'int': |
908. Smallest Range I
给定一个数组,和一个K,数组里的数加上-k<=x<=k的任意一个数字后,求数组最大数和最小数的,最小差。原题
1 | Input: A = [0,10], K = 2 |
1 | def smallestRangeI(self, A: 'List[int]', K: 'int') -> 'int': |
949. Largest Time for Given Digits
给定四个数字,返回能生成的最大时间。24小时制。原题
1 | Input: [1,2,3,4] |
方法一:排序。
1 | def largestTimeFromDigits(self, A: 'List[int]') -> 'str': |
1 | def largestTimeFromDigits(self, A: 'List[int]') -> 'str': |
914. X of a Kind in a Deck of Cards
有这样一堆数字卡牌,问是否存在一个X>=2,使得将同样数字的卡牌分为每X个一组,并且刚好所有的卡牌分完。原题
思路:使用Counter
来统计每个数字的个数,然后求这些数字的最大公约数是否大于等于2,这里思路卡了一下,因为没想到最大公约数可以通过reduce
来计算,没考虑到是可以累积的。
1 | def hasGroupsSizeX(self, deck): |
470. Implement Rand10() Using Rand7()
使用rand7
实现rand10
原题
1 | Input: 3 |
方法一:先将rand7-1变为[0, 6]然后乘7,[0,7,14,21,28,35,42]然后+[0,6]这样能将这6个数均匀地分配到每段中,得到了[0, 48]然后舍弃[40,48]剩下[0,39]然后取余得[0,9]最后加一。
1 | def rand10(self): |
1006. Clumsy Factorial
将一个阶乘的式子用*/+-
替代,给出结果。原题
1 | Input: 10 |
方法一:python此题有作弊的方法,我看排行榜中大神有的特意切到python做这道题,不过没我写得好。
1 | def clumsy(self, N: int) -> int: |
1022. Smallest Integer Divisible by K
最小的由1组成的能被K整除。原题
1 | Input: 2 |
如果有2
或5
的质因数,那么不能整除。
1 | def smallestRepunitDivByK(self, K: int) -> int: |
1028. Convert to Base -2
10进制转成-2进制。原题
方法一:负数进制时,如果余数为负数,那么商+1。
1 | def baseNeg2(self, N: int) -> str: |
方法二:在二进制上加一个负号。
1 | def baseNeg2(self, N: int) -> str: |
313. Super Ugly Number
根据指定的质数序列,找出第n个超级丑数。原题
和剑指offer中,丑数一题很像,只不过那题是固定的2,3,5三个质数。
方法一:根据之前的方法进行微调。时间要1s左右,因为遍历了两次primes
。
1 | def nthSuperUglyNumber(self, n: int, primes: List[int]) -> int: |
1 | def nthSuperUglyNumber(self, n: int, primes: List[int]) -> int: |
869. Reordered Power of 2
重新排列一个数字的各位数,判断是否能组成2的幂。原题
这题我看到是,显示拆成两个子问题,全排列和判断是否是2的幂,结果超时了,不知道为什么,我看Solution中也有这种解法,我还提交了好几次。
所以此题需要换一种思路,2的幂是指数上升的,所以,在范围内的数一共也没有几个。那么使用Counter来判断是否能组成这个数。
1 | def reorderedPowerOf2(self, N: int) -> bool: |
1025. Divisor Game
两个人做游戏,黑板上有个数N,每次找到一个0 <x<N的数,并且N能被x整除,然后替换这个N,直到找不出这样x,就输了。问给出这样一个数N,第一个人是否能赢。原题
方法一:写了一个动态规划,最后一分析实际上只要N为偶数就能赢。
1 | ans = [] |
1037. Valid Boomerang
验证三个坐标点是否共线。原题
方法一:需要注意的是,除数为0 的情况,所以这里改成了乘法。
1 | def isBoomerang(self, points: List[List[int]]) -> bool: |
1041. Robot Bounded In Circle
一个面向北的机器人进行三种操作,一种是前进,或者向左向右转。问一系列的操作中,无限循环时,机器人是否在绕圈。原题
方法一:将操作反复4次,判断是否回到原点。
1 | def isRobotBounded(self, instructions: str) -> bool: |
方法二:不需要循环四次,在一次之后,如果面向的不再是北,那么最后将会绕圈。
1 | def isRobotBounded(self, instructions: str) -> bool: |
1137. N-th Tribonacci Number
三个数的斐波那契数列。原题
1 | Input: n = 4 |
1 | def tribonacci(self, n: int) -> int: |
1073. Adding Two Negabinary Numbers
两个-2进制的数相加。原题
方法一:转成十进制相加,再转回-2进制。
1 | def addNegabinary(self, arr1: List[int], arr2: List[int]) -> List[int]: |
1154. Day of the Year
根据输入的日期,返回它是一年中的第几天。原题
方法一:使用了datetime库,开始还自己手动减,后来看评论发现有这样的方法。
1 | def dayOfYear(self, date: str) -> int: |
1155. Number of Dice Rolls With Target Sum
扔一个f面的 骰子d次,结果为target的次数。原题
1 | Input: d = 2, f = 6, target = 7 |
方法一:竞赛时用的数组,后来发现字典效率更高。此题和剑指offer中骰子题类似。
1 | def numRollsToTarget(self, d: int, f: int, target: int) -> int: |
1093. Statistics from a Large Sample
统计大量的样本数据,求最小值,最大值,平均值,众数。原题
1 | Input: count = [0,1,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |
方法一:中位数的求法这里没想到,使用二分可以完美的解决奇偶问题。
1 | def sampleStats(self, count: List[int]) -> List[float]: |
1103. Distribute Candies to People
发糖果,按照顺序每个人比上一人多一颗,发到最后再循环。原题
1 | Input: candies = 7, num_people = 4 |
方法一:此题做法和Lee神不谋而合。
1 | def distributeCandies(self, candies: int, n: int) -> List[int]: |
1109. Corporate Flight Bookings
通过给定的一些区间,确定每天的座位数。原题
1 | Input: bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5 |
方法一:此题暴力法会超时。核心在于记录变化的状态,然后累加求结果。
1 | def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]: |
1175. Prime Arrangements
质数排列。原题
1 | Input: n = 5 |
1 | def numPrimeArrangements(self, n: int) -> int: |
1360. Number of Days Between Two Dates
计算两个日期之间的天数。原题
1 | Input: date1 = "2020-01-15", date2 = "2019-12-31" |
方法一:简单的datetime
模块方式。
1 | def daysBetweenDates(self, date1: str, date2: str) -> int: |
方法二:有个公式,如果将1月二月看成是13月和14月,那么月份转化天数有个公式(153 * m + 8) // 5
1 | def daysBetweenDates(self, date1: str, date2: str) -> int: |
1363. Largest Multiple of Three
组成的最大的3的倍数。原题
1 | Input: digits = [8,1,9] |
方法一:数学。
- Calculate the sum of digits
total = sum(A)
- If
total % 3 == 0
, we got it directly - If
total % 3 == 1
and we have one of 1,4,7 in A:
we try to remove one digit of 1,4,7 - If
total % 3 == 2
and we have one of 2,5,8 in A:
we try to remove one digit of 2,5,8 - If
total % 3 == 2
:
we try to remove two digits of 1,4,7 - If
total % 3 == 1
:
we try to remove two digits of 2,5,8
1 | def largestMultipleOfThree(self, A): |
1493. Longest Subarray of 1’s After Deleting One Element
删除一个元素,子数组有最长的1、子数组长度。原题
1 | Input: nums = [1,1,0,1] |
方法一:双端队列,其实是求最多包含1个0的滑动窗口长度。
1 | def longestSubarray(self, nums: List[int]) -> int: |
方法二:Lee215的解法,还是选择维持了一个最大的长度,所以没用while 而是if,这样也不用每次max来求值。
1 | def longestSubarray(self, nums: List[int]) -> int: |
537. Complex Number Multiplication
两个负数相乘。求结果,需要注意的是这里会多一个+。原题
1 | Input: "1+-1i", "1+-1i" |
方法一:内置库。这里format时不能用d,因为都是float。但是%却可以做到。
1 | def complexNumberMultiply(self, a: str, b: str) -> str: |
方法二:不用内置库。
1 | def complexNumberMultiply(self, a: str, b: str) -> str: |
1 | def complexNumberMultiply(self, a, b): |
794. Valid Tic-Tac-Toe State
在一个九宫格里下棋,谁连上3个就算赢,问给出一个棋子局面,判断是否可能下出来。原题
方法一:case挺多的,需要想明白判断条件,基本就是请求x,o的分别连3的个数,然后和分别的棋子数,最后判断。
1 | def validTicTacToe(self, b: List[str]) -> bool: |
1 | b = '|'.join(board) |
227. Basic Calculator II
计算式子,没有括号,包含加减乘除和小数点。原题
1 | Input: " 3+5 / 2 " |
方法一:eval算是作弊了,这个stefan的方法不错。用了生成器。
1 | def calculate(self, s: str) -> int: |
640. Solve the Equation
解方程,方程中只有x一个变量,只有加减操作。原题
1 | Input: "x+5-3+x=6+x-2" |
方法一:首次AC的方法。正则调了半天,因为不止一为数。
1 | def solveEquation(self, equation: str) -> str: |
1 | def solveEquation(self, equation: str) -> str: |
1 | def solveEquation(self, equation: str) -> str: |
319. Bulb Switcher
有n个开关控制n个初始化为关的灯泡。从1开始,每次隔1,2,3,4..n开这些开关,问最后有多少个开着的灯。原题
方法一:这题有点像脑筋急转弯,我分析出了只有1~n的数有奇数个约数,那么最后就是开着的。然后什么样的数有奇数个约数,看了stefan后恍然大悟,原来是开方。
1 | def bulbSwitch(self, n: int) -> int: |
592. Fraction Addition and Subtraction
分数运算,有负数,只有+-操作,最后要返回一个分数,如果是整数的话,需要分母1。
1 | Input:"-1/2+1/2" |
方法一:cheat 写法。
1 | def fractionAddition(self, expression: str) -> str: |
方法二:自己实现了一个。
1 | def fractionAddition(self, expression: str) -> str: |
1 | def fractionAddition(self, expression: str) -> str: |
1 | def fractionAddition(self, expression: str) -> str: |
397. Integer Replacement
给定一个数,偶数可以/2,奇数可以+1,-1,问最少多少步能到1。
1 | Input: |
方法一:递归。
1 | def integerReplacement(self, n: int) -> int: |
方法二:这是一个贪心的方法。首先需要推导证明。//2的方式一定是最快的,因为2/1也只用了1步。
1 | f(1) = 0 |
1 | def integerReplacement(self, n): |
372. Super Pow
求大数的幂。幂也可以很大。对1337的余数。
1 | Input: a = 2, b = [1,0] |
方法一:我用math.pow()
, 超过了range error
了。而stefan的pow就可以,难道因为取余运算放到方法里就很快?即使是这种方式,将1337用%取余也会超时。
1 | def superPow(self, a: int, b: List[int]) -> int: |
方法二:Stefan的方法。
1 | def superPow(self, a: int, b: List[int]) -> int: |
面试题 16.14. 最佳直线
平面上有一些点,画一条直线,问穿过做多点的线,最开始的两个点的索引是什么。
1 | 输入: [[0,0],[1,1],[1,0],[2,0]] |
方法一:暴力,O(n^3)。
1 | def bestLine(self, points: List[List[int]]) -> List[int]: |
方法二:评论区学到的方法,改了一下。哈希表记录,一条直线有斜率和截距来确定。以此为hash。截距怎么求都忘了,推导了半天。这里索引比较乱,所以用了namedtuple。
1 | def bestLine(self, points: List[List[int]]) -> List[int]: |
1 | def bestLine(self, points: List[List[int]]) -> List[int]: |
60. Permutation Sequence
全排列中的第k个。原题
1 | Input: n = 3, k = 3 |
方法一:这道题写法进行了一些改进,严格意义上来说不算回溯,不知道为什么官方标签贴了一个回溯,只是做了剪枝。
1 | def getPermutation(self, n: int, k: int) -> str: |
方法二:改变一下思路,根据k的大小来确定每个位置的数。这道题想了不到个小时,最终原创出自己的写法。耗时36ms,beats 99%。果然数据规律才是致命的降维打击。
1 | def getPermutation(self, n: int, k: int) -> str: |
divmod
内置函数来求值。
1 | def getPermutation(self, n: int, k: int) -> str: |
1643. Kth Smallest Instructions
第k个最小的指令,其实是求R*'V'+C*'H'
的第k个最小的非重复的全排列。
1 | Input: destination = [2,3], k = 1 |
方法一:可惜,比赛时没有足够时间来做,是想到了数学法,也想起来和60题很像,区别在于60题没有重复,这里需要去重。评论区的一个解法。
1 | def kthSmallestPath(self, destination: List[int], k: int) -> str: |
1621. Number of Sets of K Non-Overlapping Line Segments
给你一维空间的 n 个点,其中第 i 个点(编号从 0 到 n-1)位于 x = i 处,请你找到 恰好 k 个不重叠 线段且每个线段至少覆盖两个点的方案数。线段的两个端点必须都是 整数坐标 。这 k 个线段不需要全部覆盖全部 n 个点,且它们的端点 可以 重合。返回方案数。
方法一:比赛时没做出来,卡在第二题,想到了组合。看到了Lee的答案。给你n个点,k个线段可以共享端点。这个问题可以转化成:
给你n+k-1个点,每个线段不可以共享端点。在k个线段之间各补一个点。所以只需要求出从这些点出选出2k个点的组合。因为每两个相邻的点连成一段,所以是2k。
1 | def numberOfSets(self, n: int, k: int) -> int: |
458. Poor Pigs
说有这么1000桶里面装了水,其中有一桶里面是毒药。你可以让无数头猪来这些水,但是每头猪15分钟只能喝一次,不过可以同时喝若干桶水。你要在1个小时之内知道哪个桶是有毒药的。最少需要多少头猪。
方法一:数学方法。这题比较难想。从一只猪开始思考。60分钟一共可以喝4次,不过可以检测5个桶,因为喝完最后的没有死,所有毒药在没有喝的桶。然后是两只猪,可以检测5**2个桶,将25个桶想象成一个平面。一只猪每次按照行来喝,另一只猪按照列来喝。最后通过行列可以确定毒药的位置。3只猪的时候要想象成三维的平面,每次每只猪要喝25桶的水,分别按照x, y, z轴的顺序。最后三个维度的坐标可以确定。本质上此题是一道信息论的题。知乎有个大佬通过信息熵来解此题,不明觉厉。
1 | def poorPigs(self, buckets: int, minutesToDie: int, minutesToTest: int) -> int: |
1744. Can You Eat Your Favorite Candy on Your Favorite Day?
能否在某一天吃到某种特定的糖果。三个规则:每天至少吃一个;从类型小的吃,吃完才能吃下个类型;查询条件中限制每天最多吃多少糖果。
1 | Input: candiesCount = [7,4,5,3,8], queries = [[0,2,2],[4,2,4],[2,13,1000000000]] |
方法一:比赛时没有做出来,结束后18分钟做出来了。一个条件想错了应该是pre_sum[can+1]>=day+1
,而不是pre_sum[can]>=day
。
其实能否吃到,只有两个条件。一个是那一天能不能够到指定的糖果,每天按照最多的吃。另一个是每天只吃一个,到了那天该种糖果还有没有剩余。
1 | def canEat(self, candiesCount: List[int], queries: List[List[int]]) -> List[bool]: |
1780. Check if Number is a Sum of Powers of Three
判断一个数是否由不一样3的幂,组成。
1 | Input: n = 91 |
方法一:比赛时,暴力求出了所有的可能的结果,然后判断。1500ms。
1 | class Solution: |
1 * 3^0
+ 0 * 3^1
+ 1 * 3^2
-> True11 =
2 * 3^0
+ 0 * 3^1
+ 1 * 3^2
-> False, because there is a 2
as coeficient。如果余数出现2,就不能组成这个数。
1 | def checkPowersOfThree(self, n: int) -> bool: |
1819. Number of Different Subsequences GCDs
求一个数组的任意子序列所有的数的最大公约数,有多少种。
1 | Input: nums = [6,10,3] |
方法一:竞赛没有参加,比较是比赛写不出来的题。看别人的答案看了很久。首先,枚举子序列一定会超时,这里要用逆向思维,枚举公约数。当指定了公约数之后,找会不会有这样一个子序列能满足这个公约数。这些子序列中的数一定是这个公约数的倍数。y表示公约数,x为组成子序列的数,g值会逐渐减小,直到等于y表示,找到了这样一个子序列的最大公约数为g。这里迷惑了很久为什么要break,因为题中要求的是种类的个数。所以不需要再往下进行。
1 | def countDifferentSubsequenceGCDs(self, nums: List[int]) -> int: |
523. Continuous Subarray Sum
是否存在连续的子数组和为k的倍数。
1 | Input: nums = [23,2,4,6,7], k = 6 |
方法一:前缀和+哈希。没有想出来。很关键的一点,是当pre_sum[j]-pre_sum[i]=n*k
即pre_sum[j]
和pre_sum[i]
对k取余有相同的结果。想明白这点,此题就很简单。
1 | def checkSubarraySum(self, nums: List[int], k: int) -> bool: |