认真是一种态度
坚持是一种选择

0%

小技巧 - 计算下一个周几间隔天数

问题

假设一周中的7天分别用0-6表示周日、周一、周二、周三、周四、周五、周六。
给定一个当前值n,n的范围属于[0,6],表示当天是周几。
给定一个目标值k,k的范围属于[0,6],表示要到达周几,如果当前天超过了k,则k应是下一周的周几。
设计一个函数dayInterval,计算从当天到下一个目标天,之间间隔了多少天。

例如:
当n=1,k=1,表示从周一到下一个周一经历的天数,函数应该返回7
当n=2,k=1,表示从周二到下一个周一经历的天数,函数应该返回6
当n=0,k=1,表示从周日到下一个周一经历的天数,函数应该返回1

该函数只可以包含一行代码,即你要用一行纯计算表达式得出结果。

分析

假设k=1,表示要达到下一个周一的天数,那么n属于[0,1,2,3,4,5,6]分别对应着结果[1,7,6,5,4,3,2]

假设k=2,表示要达到下一个周二的天数,那么n属于[0,1,2,3,4,5,6]分别对应着结果[2,1,7,6,5,4,3]

通过观察和分析可以知道,从本周的某天到达下个目标天最大时间跨度是7天,最小天数是1天,也就是说答案一定是在[1-7]之间,那么k和这个结果又有什么关系呢?画几个图来看看。
假如以周天为起始天,当k=0时,即从本周各天到达下一个周天,结果是[7,6,5,4,3,2,1],存在这样的关系:

可以看到,当我们要计算到下一个周几的时候,就让本周几对齐到索引0,因为从一个周几到下一个相同的周几一定是经历7天,即n等于k时,结果一定是7。所以,当k=1时,就让1对齐到索引0,从周一到下一个周一一定是7天。
图像表示为将上一行全部左移了一位,移出去的周天,应该填充到最右端,和最后一位对齐,因为每周都是周而复始的,周六之后是周天。虚框代表移除的部分,实框表示向右填补的部分。

可以想象成一个由0到6按顺序组合的圆环,它可以无限滚动。
k=2,让2对齐到索引0:

实现

由于定义的0为周天,所以我们想让周几对齐到索引0,减去周几这个数值即可,而索引即对应着数组[7,6,5,4,3,2,1]的值,不一定非要初始化这样一个数组,因为它们有这样一个关系,索引+对应的数组值=7,这个是不变的。所以我们的任务只要求得偏移后每一天对应的索引即可,用7减去索引即得到对应的数值,无需通过初始化数组去查找索引对应的值。

将n-k即得到对齐后的索引,超出左侧的部分索引变成了负数,而超出的部分应该在右侧对齐,这里有个常规技巧,超出部分(负数部分)直接加上数组长度即可,为了保持统一性,使得加上数组长度后正数部分不会超出数组长度,可以再对数组长度取模,这样只需一个表达式将索引转变成有效索引。这里的数组长度是7,所以索引等于(n-k+7)%7

这题的答案就是:

1
2
def dayInterval(n,k):
return 7-(n-k+7)%7

如果你是使用python语言的话,那么以上解答可以看作是对以下代码的另一种表述(python允许索引为负数,-1表示最后一个元素,以此类推):

1
2
def dayInterval(n,k):
return [7,6,5,4,3,2,1][n-k]