中级农民
- 积分
- 104
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2018-3-17
- 最后登录
- 1970-1-1
|
Day 8:
Q1. Self Dividing Numbers 【easy】
题目理解:1)输入:两个整数left、right,表示上下限
2)输出:整数,表示从left到right之间的数所有满足“Self Dividing”的个数
3)其中1 <= left <= right <= 10000
4)Self Dividing:该整数的每一位数字(1~9),都能整除这个整数,(不能包含0)
解决方法: Brute Force。遍历从left到right的每个整数num,并对每个整数进行模自己的每一位数字的操作进行while循环:每次令curr = num,a = curr%10 若curr%a != 0 跳出while循环,之后每次curr/=10,如果最后直到curr=0都没有跳出,ans+=1,之后对下一个num操作。
注:最开始也考虑过对每一个能整除的1~9的整数分别判断,但是实现起来比较麻烦,且不会使整个计算过程更快,所以直接循环每个数字,循环每个数的每一位直接计算即可。
Q2. My Calendar I 【Medium】
题目理解:1)输入:整数对start、end,表示时间的起始和结束时间
2)输出:bool结果,表示给定的事件是否可以被执行
3)日程表要求不能在同一个时间段,同时执行两个事件
解决方法:Brute Force。循环所有已安排在日程中事件,并分别判断跟待定事件是否存在重叠。根据题目要求可知,两个事件存在非零交集的关系为:start1<end2 且start2<end1。在循环中,若出现任一事件与待定事件重叠,返回False;若已安排所有事件全部遍历均无重叠,那么将新事件加入日程列表,并返回True。
class MyCalendar(object):
def __init__(self):
self.calendar = []
def book(self, start, end):
for s, e in self.calendar:
if s<end and start<e: return False
self.calendar.append((start, end))
return True
Q3: My Calendar II 【Medium】(第二题的升级版)
题目理解:1)输入:整数对start、end,表示时间的起始和结束时间
2)输出: bool结果,表示给定的事件是否可以被执行
3)日程表要求不能在同一个时间段,同时执行三个事件
解决方法:跟第二题类似,同样要对每个已安排事件遍历比较,不同点在于因为可以同时进行两个事件,所以需要记录任何存在overlap的两事件之间重叠的时间。在判断是否可以添加新日程时 ,若新事件的开始结束时间与我们已经记录的overlap有重叠时,要返回False;当新日程跟所有overlap都不重叠时,在更新日程的同时,还要更新overlap,最后返回True 。
class MyCalendarTwo(object):
def __init__(self):
self.calendar = []
self.overlap = []
def book(self, start, end):
for so, eo in self.overlap:
if start<eo and so<end: return False
for s, e in self.calendar:
if start<e and s<end:
self.overlap.append((max(s,start),min(e,end)))
self.calendar.append((start, end))
return True
注:Q2、Q3虽然标注 为Medium,但整体解题思路和代码实现过程都很简单明了,二者的解题方法也十分类似。
Q4: Flood Fill 【easy】
题目理解:1)输入:二维矩阵image(元素均为整数,不同数字代表不同颜色),sr,sc(表示给定矩阵内的坐标),newColor(整数)
2)输出:新的二维矩阵(跟原输入尺寸相同)
3)规则:对原数组中坐标为(sr,sc)的点进行染色操作,该操作会赋予给定坐标一个颜色newColor,并会对跟(sr,sc)点原来颜色相同且上、下、左、右连通的所有坐标点进行同样的操作。
解决方法: 递归。根据3)中描述的染色规则,可以发现对于给定点周围所有同等地位的坐标进行同样操作。因此,我们首先自定义一个染色函数fill(image, x, y, m, n, orgColor, newColor),其中m、n为原矩阵的行、列数,x、y表示将要进行染色的横、纵坐标,在写函数时需要注意横纵坐标的范围问题,以及染色边界(不同颜色交界处),并在内部不断调用原函数,对原色相同的上下左右方向进行染色,完成递归调用。
最后调用自定义函数,并输出递归过后的新image即可。具体代码非常简洁(Python):
class Solution(object):
def floodFill(self, image, sr, sc, newColor):
if image[sr][sc]==newColor: return image
m,n = len(image), len(image[0])
def fill(image, x, y, m, n, orgColor, newColor):
if image[x][y] == orgColor:
image[x][y] = newColor
if x>0: fill(image, x-1, y, m, n, orgColor, newColor)
if y>0: fill(image, x, y-1, m, n, orgColor, newColor)
if x<m-1: fill(image, x+1, y, m, n, orgColor, newColor)
if y<n-1: fill(image, x, y+1, m, n, orgColor, newColor)
fill(image, sr, sc, m, n, image[sr][sc], newColor)
return image
Q5: House Robber 【easy】
题目理解:1)输入:整数数组nums,表示某条街上每个house里可以盗取的财产数量
2)输出: 整数,表示可以在不触发警报的前提下,能够盗取的所有财产数量
3)不触发警报的条件:不能连续盗窃两个相邻的house
解决方法: 递归/递推。因为递归和递推为同一种思想的正反实现,我这里就只详细写一种。以递推为例,首先要考虑起始条件,如果没有house(n=0),就没得偷,返回0;只有一家的话,至多只能偷一家,直接输出nums[0];若有两家,那么偷钱多的。之后我们可以考虑一下递推关系。我们需要将问题稍做转换,我们假定每次都从左向右偷东西,我们来考虑偷到第i家结束时,强盗能够得到的最多财产数。这样对于抢到每个住户结束都会有的此时的最大值,所以当i=n-1(最后一个住户)时,就是我们要的答案。在不越界的情况下,中间的传递关系可以表示为:sums[i] = max(sums[i-1],sums[i-2]+ nums[i]) |
|