刷题日常——Leetcode386字典序排数
给你一个整数 n
,按字典序返回范围 [1, n]
内所有整数。
你必须设计一个时间复杂度为 O(n)
且使用 O(1)
额外空间的算法。
开始被后面那句话唬住了愣是想不出来,但是冷静下来以后,改变了思考方式:
结果是按照字典序来排列,那我按照字典序的规则每次让前一个数加1不就行了吗。
现在看是理所当然的答案,但是开始的时候并没有往这个方向想。能找到答案是因为我改变了思考方式,我想的不再是怎么得到整体的答案,即按照字典序排列的那一堆整数;而是得出那个整体的其中一个答案的逻辑,再把这个逻辑应用于每一个单独的答案。
对于这道题而言,就是怎么根据前一个数得到当前位置的数。
通过观察示例发现,字典序的+1无非两种情况:
末尾添0.
正常+1.
正常+1和一个int型一样,唯一的区别是进位的时候需要去掉后一位的0。然后进位还要分两种情况,一种是数字加到比n大了,一种是低位等于9了。
于是就有了这个代码:

结果9ms,算是慢的了但是没什么优化空间。然后就直接去看了官方的题解,发现......
官方题解的想法和我的想法是一致的,只是有一点有疑问:

number*10<=n真的可以认为number*10就是下一个字典序整数吗?
我想找几个反例,但是显然是没有的......那么反过来思考吧,末尾添0总共有几种情况:
进位以后。第n位等于9以后,下一个数没有第n位,下下个数的第n位一定是0。比如1239的下一个数是124,再下一个是1240,这是字典序的规则决定的。
初始值1。
第一种情况,1239既然存在就是确定小于等于n的,如果1239等于n,那么循环会直接结束,因此n一定>=1240。也就是说,num x 10绝对不会比n大。
说人话就是末尾添0还比n小的情况,只有进位以后。而字典序的规则决定了进位以后的下一个数,一定是number*10。
以上。