题目:
A format for expressing an ordered list of integers is to use a comma separated list of either
individual integers
or a range of integers denoted by the starting integer separated from the end integer in the range by a dash, ‘-’. The range includes all integers in the interval including both endpoints. It is not considered a range unless it spans at least 3 numbers. For example (“12, 13, 15-17”)
Complete the solution so that it takes a list of integers in increasing order and returns a correctly formatted string in the range format.
Example:
solution([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20])
# returns "-6,-3-1,3-5,7-11,14,15,17-20"
我的思路:
题目让我们把连续的n个数字简写成一个区间,如1,2,3,4 变成 1-4。由于我们需要看到下一个数字,才能判断前一个数字是省略还是加入list,所以我用了两个指针last和now,指向list里前后两个相邻的数字。如果出现了两个相邻的数字,则第二个数字有被省略的可能性,而如果出现三个连续的数字,则中间那个一定被省略。所以我使用了两个标记,记录当前的状态,potential 和 omit,分别表示,当前数字有可能被省略和正在当前数字正在被省略过程中。
我的解答:
def solution(args):
length = len(args)
if length <= 2:
return ",".join(args)
args.append(0)
last = args[0]
now = args[1]
potential = 0
omit = 0
result = str(args[0])
for i in range(1,length+1):
print(args[i])
now = args[i]
if now - last == 1 and potential == 0 and omit == 0:
potential = 1
elif now - last == 1 and potential == 1 and omit == 0:
omit = 1
potential = 0
result += "-"
elif now - last == 1 and potential == 0 and omit == 1:
pass
elif now - last != 1 and omit == 1:
omit = 0
result = result + str(last) + "," + str(now)
elif now - last != 1 and potential == 1:
potential = 0
result = result + "," + str(last) + "," + str(now)
else:
result = result + "," + str(now)
last = args[i]
return result[:-2]
Most Clever:
做完题目看一下题后投票clever最多的答案:
def solution(args):
out = []
beg = end = args[0]
for n in args[1:] + [""]:
if n != end + 1:
if end == beg:
out.append( str(beg) )
elif end == beg + 1:
out.extend( [str(beg), str(end)] )
else:
out.append( str(beg) + "-" + str(end) )
beg = n
end = n
return ",".join(out)
为了防止溢出,我在args后append了一个0,他在args后加了一个"",空的字符串。
他用了两个指针,beg(begin) 和 end,表示连续数字的开头和结尾。根据开头和结尾的差值来分类讨论:如果开头结尾相等(不连续),将该数字直接加入out列表;如果开头结尾相差1(有且仅有两个数字连续),将开头结尾两个数字都加入out列表;如果开头结尾相差1以上(有两个以上数字连续),将开头结尾两个数字中间加一个 “-” ,然后加入out列表。
总结:
两种方法思路一致,但Most Clever的实现方式比我清晰简洁很多。我的指针间距永远是1,即每往后一位,都分类讨论,显示在最后return的结果中。而他的两个指针代表着每一段的开头和结尾,每一段成型后再加入return的结果中,这样跟方便分类讨论,不需要加入额外的变量来标记状态。