安全プランを証明する:N出現頻度(Javaは)1から1の整数であります

タイトル:整数を入力してN、回数が出現からの要求は、n 10進整数1を表します。1から12までの数を含む入力12は、例えば、図10に示すように、これらの11の整数を有し、そして5回12,1の合計がありました。

時間効率のよいソリューションを考慮せずに、少し難しい取りに行ったの申し出に頼っていました

    あなたはインタビューの中で、この問題が発生した場合は、最も直感的な方法を考えるのが最も可能な候補、各整数が表示されますのための1からnまでの累積数。我々は、単一の数字ではない裁判官で割った後、10次に、この数は10以下である場合に1の残りの部分を要求する一桁の整数裁判官によってそれぞれが疑われると。

public int numberOf1BetweenAndN(int n){  
        int number = 0;  
        for(int i = 1;i<= n;i++){  
            number+=numberOf1(i);  
        }  
        return number;  
    }  
    public int numberOf1(int n){  
        int number =0;  
        while(n!=0){  
            if(n %10 == 1)  
                number++;  
            n = n/10;  
        }  
        return number;  
    }  
    上記の考えから、我々は剰余演算し、この数は各桁の1に表示された回数を送信するために確認する必要があります。あなたが番号を入力し、N、N- O(LOGN)のビットを持っている場合、我々は、各ビットが1でないかを決定する必要があり、それの時間計算量はO(N * LOGN)です。入力Nが非常に大きい場合、運転効率が高くない、計算の多くを必要とします。インタビュアーは、このアルゴリズム満足されることはありません
インタビュアーリフレッシュをしましょう、時間の数字の法則からソリューションの効率を向上させる大幅に進めるために

   あなたは、各番号1の数を計算したくない場合は、唯一のデジタルでの法律を見つけるために、1で発生する可能性があります。法を見つけるために、我々は、一例として、分析するために21345のような少し大きめの数を、使用することをお勧めします。私たちは21345の最上位ビットを除くが1345私たちを見ているので、他のセクションは、その理由は、再帰的な思考を使用して容易である21345.に1346年から分割され、2つの段落に分けられ、1は1から1345からである1から21345までのすべての数字を入れて番号1346から21345 1が表示されます。二つの状況に分かれて1が表示されます:1、最も高いレベルで表示され、1が他の場所に表示されます。21345,1へ1346年はこの数字は、合計で10 000、または10 ^最高レベルがなされている最も高い位置10000から19999 10000に表示されます。私たちは、一般的な見つけることができます:1346年は11345,1にある場合は最も高い位置10000から11345、最も多くを取り除いた後に残ったデジタル+1で2346回の合計、の出現、1万1以上、1つの外観に表示されます最大数は10 ^最高レベルです。

    その後で最高レベルに加えて、状況その他の4桁の1が表示さを分析。二つのセグメント、1346から11345と11346から21345に分け、これらの4つの番号20 000後に現れる1346から21345の数、残りの4桁の各セグメントは、選択ビットが1で、残りの3つは、0であることができます10の-9これらの数は任意の配置、出現10 ^ 2 * 3 * 4 = 8000の合計数に応じて、原理の組み合わせを選択しました。私たちは、一般的な見つけることができますので、1346-n1345場合は、分けn個のセグメントすることができ、すなわち1つの他の4桁の最上位ビットがある以外の時間に現れN * 4 * 1000;

	public static int numberOf1BetweenAndN(int n){  
		if(n<=0){
			return 0;
		}
		String str=n+"";              
        return numberOf1(str);  
    }  
    public static int numberOf1(String str){
    	char[] strN=str.toCharArray();
    	int length=strN.length;   	
    	if(length==1&&strN[0]=='0'){
    		return 0;
    	}
    	if(length==1&&strN[0]>'1'){
    		return 1;
    	}
    	int numFirstDigit=0;
    	if(strN[0]>'1')
    		numFirstDigit=(int) Math.pow(10,length-1);
    	else if(strN[0]=='1')
    		numFirstDigit=Integer.parseInt(str.substring(1))+1;
    	int numOtherDigits=(int) ((strN[0]-'0')*(length-1)*Math.pow(10, length-2));    	
    	int numRecursive=numberOf1(str.substring(1));   
    	return numFirstDigit+numOtherDigits+numRecursive;
    	
    }  


公開された118元の記事 ウォン称賛35 ビュー120 000 +

おすすめ

転載: blog.csdn.net/abc7845129630/article/details/52738784
おすすめ