这个是《剑指OFFER》上的一个面试题,题目要求写出n位数,当然题目的陷阱就是n可能很大超过long long的位数,所以很容易想到用高精度加法去实现一个,当然这个方法并不好,最方便的方法是用“秒表”的方法,直接写出这些结果。
当然,每次的结果可以认为是一个前缀加上0~9的遍历,所以我把它称作为秒表法,整个数字的写法就犹如一个秒表,低位的走完了就进一位,然后再进行低位的计数。
所以整个问题的算法也可以用如下递归写出:
public class OneToN
{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
int n = s.nextInt();
print1ToN(n, 0, "");
}
public static void print1ToN(int n , int idx , String prefix)
{
if(idx == n)
{
System.out.println(prefix);
}
else
{
for(int i=0 ; i<10 ; i++)
{
String temp = "";
if(!"".equals(prefix) || i!=0 || (idx+1) == n)
temp = prefix + i;
print1ToN(n,idx+1 , temp);
}
}
}
}
上面的递归也很清晰,由idx和n控制何时回归,而每次递归时就更新这个前缀就行了。
当然,模拟的方法不仅是递归一种,也可以通过栈来记录前缀(注意,这里不是通过栈记录递归,但是思想是一致的)。方法如下:
package jpbirdy;
import java.util.Scanner;
import java.util.Stack;
/**
* Created by jpbirdy on 2014/9/2.
*/
public class OneToN
{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
int n = s.nextInt();
print1ToN(n);
}
public static void print1ToN(int n)
{
Stack<Integer> s = new Stack<Integer>();
s.push(0);
while(!s.empty())
{
if(s.size() == n)
{
boolean flag = false;
for(int i=0 ; i<s.size() ; i++)
if(flag || s.get(i)!=0 || i== s.size()-1)
{
System.out.print(s.get(i));
if(s.get(i)!=0)flag = true;
}
System.out.println();
while(!s.empty())
{
int top = s.pop();
if(top < 9)
{
s.push(top+1);
break;
}
}
}
else
s.push(0);
}
}
}
当然,两种算法的思想都是模拟,过程就类似一个秒表的计数过程。这两种方法都优于通过实现高精度进行实现。