Tá aí.
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Locale;
public class Serie
{
    private static final int MAX_DOUBLE = 308;
    private static final double T[] = new double[MAX_DOUBLE];
    
    private static final int MAX_BD = 5000;
    private static final BigDecimal T_BD[] = new BigDecimal[MAX_BD];
    
    private static final BigDecimal TEN_BD = BigDecimal.valueOf(10);
    //private static final BigDecimal ZERO_BD = BigDecimal.valueOf(0); Excluida
    
    /*[01]-----------------------------------------------------------
    *            Funcao de aproximacao de Gorducho
    -----------------------------------------------------------------*/
    public static double gordsApproach(int n, int k)
    {
        return 1 - Math.exp(-(n/Math.pow(10,k)));
    }//fim de gordsApproach()
    /*[02]-----------------------------------------------------------
    *                 Retorna o erro relativo
    -----------------------------------------------------------------*/
    public static String relativeErr(String result, double estimate)
    {
        double bdResult = new BigDecimal(result).doubleValue();
        double err = Math.abs(bdResult - estimate)/bdResult * 100;
        return String.format(Locale.US,"Erro de aproximacao = %8.4f %%",err);
    }//fim de relativeErr()
    /*[03]-----------------------------------------------------------
    *   Retorna uma String com o mesmo char repetido howManyTimes
    -----------------------------------------------------------------*/
    public static String repeat(char c, int howManyTimes)
    {
        char[] array = new char[howManyTimes];
        Arrays.fill(array,c);
        return new String(array);
    }//fim de repeat()
    /*[04]-----------------------------------------------------------
    *         Retorna 10 elevado a power em BigDecimal
    -----------------------------------------------------------------*/
    public static BigDecimal exp10(int power)
    {
        return new BigDecimal("1" + repeat('0',power));
    }//fim de exp10()
    /*[05]-----------------------------------------------------------
    *               Retorna p(n,k) em BigDecimal
    -----------------------------------------------------------------*/
    public static BigDecimal p3(int n, int k)
    {
        int dif = n - k;
        BigDecimal s = 
            new BigDecimal(Integer.toString(dif + 1)).multiply(exp10(dif));
        
        BigDecimal pow = new BigDecimal("1");
                    
        for (int recursiveN = dif; k <= recursiveN; recursiveN--)
        {
            //if (T_BD[recursiveN].compareTo(ZERO_BD) == 0) Excluida
            if (T_BD[recursiveN] == null)  
                T_BD[recursiveN] = (p3(recursiveN,k));
           
            s = s.subtract(T_BD[recursiveN].multiply(pow));
           
            pow = pow.multiply(TEN_BD);
        }
        
        return s;
    }//fim de p3()
    /*[06]-----------------------------------------------------------
    *                 Retorna p(n,k) em double
    -----------------------------------------------------------------*/
    public static double p2(int n, int k)
    {
        int dif = n-k;
        double s = Math.pow(10,dif) * (dif+1);
        double pow = 1;
             
        for (int recursiveN = dif; k <= recursiveN; recursiveN--)
        {
            if (T[recursiveN] == 0) T[recursiveN] = p2(recursiveN,k);
            s -= T[recursiveN] * pow;
            pow *= 10;
        }
        
        return s;
    }//fim de p2()
    /*[07]-----------------------------------------------------------
    *                  Primeira versao de p(n,k)
    -----------------------------------------------------------------*/
    public static double p(int n, int k)
    {
        if (n<k) 
            return 0;
        else
        {
            double s = Math.pow(10,n-k) * (n-k+1);
            
            for (int i = 0; i <= (n-k); i++)
                s = s - p(n-k-i,k) * Math.pow(10,i);
            return s;
        }
    }//fim de p()
    /*[08]-----------------------------------------------------------
    *                   Programa principal
    -----------------------------------------------------------------*/
    public static void main(String[] args)
    {
        int k = 3;
              
        //for (int i = k; i <= MAX_DOUBLE; i++)
            //System.out.println("P("+i+") = " + p2(i,k)/Math.pow(10,i));
        
        /*
        Inicializa com zeros (em BigDecimal) o array T_BD[]
        */
        //for (int i = 0; i <= MAX_BD - 1; i++) T_BD = ZERO_BD;  Excluida! 
        
        /*
        Lista resultados em BigDecimal de k a MAX_BD
        */
        for (int i = k; i <= MAX_BD; i++)
        {
            String bdResult = p3(i,k).toString();
            int lgth = bdResult.length();
            
            /*
            Retira os zeros a direita no resultado
            */
            for (int j = lgth - 1; j >= 0; j--)
                if (bdResult.charAt(j) != '0')
                {
                    bdResult = bdResult.substring(0,j+1);
                    break;
                }
            
            /*
            "Divide" p3(i,k) por 10 elevado a i
            */
            String result = "0." + repeat('0', i - lgth) + bdResult;
            
            /*
            Formata a String de saida
            */
            String s = relativeErr(result, gordsApproach(i,k)) +
                       String.format("%14s",String.format(" P(%d,%d) = ",i,k)) +
                       result;
                       
            
            System.out.println(s);
     
        }//fim do for i
     
        System.exit(0);//Aborta programa antes de executar o loop de simulacao
            
        /*
            Obtem por simulacao os mesmos resultados calculados pela
            funcao p(n,k)
        */    
        double limit = 999;
        for (int a = 3; a <= 9; a++)
        {
            int count = 0;
                               
            for (int b = 0; b <= limit; b++)
                if (String.valueOf(b).contains("123")) count++;
            
            System.out.println(limit+" "+count+" P("+a+") = "+(double)count/(limit + 1));
            
            limit = limit * 10 + 9;
        }
       
    }//fim de main()
    
}//fim da classe Serie
*Fonte monoespaçada
**Fiz pequenas alterações para retirar uma complicaçãozinha desnecessária. As linhas excluídas estão em vermelho, como comentários. A linha incluída está em verde.