LC330-google面試2016

shuaishuai3409發表於2016-02-29

已知:整數陣列A,第一個元素為1,且元素由小到大已排好序,不重複。
目標:輸入整數n,要求1~n內所有整數都能由陣列A的任意元素之和表示,那麼應該至少往陣列A裡填補多少元素。請輸出填補元素個數。
舉例:A=[1,5,10] n=20;1~20內的數都要由A中的任意元素之和表示,那麼應該往A裡填補元素2,4。答案輸出2個。


思路:簡單方法就是遍歷,從1遍歷到n,看陣列A中需要補充哪些元素,但這樣需要不斷的計算A中下一個補充元素之前的任意元素之和,時間複雜度會很高。這題可以考慮一下貪心演算法。每次填補的元素依賴於當前已經做出的選擇。

package google2016Interview1ArrayPatch;

import java.util.Scanner;

public class ArrayPatch {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int []a=new int[10];
        a[0]=1;a[1]=5;a[2]=10;
        System.out.println("input n:");
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        arraypatched(a,n);

    }

    private static void arraypatched(int[] a, int n) {
        // TODO Auto-generated method stub
        int len=0;
        for (int i = 0; i < a.length; i++) {
            if(a[i]!=0){
                len++;
            }

        }
        //System.out.println(len);
        int m=3,i=1,sum=3,count=0;//不用移動陣列,只要記錄下和就行


        if(a[1]==2) i++;
        else count++;

        while(m<=n){

            if(m<a[i]){
                count++;
                sum=2*sum+1;
                m=sum;

            }
            else {
                sum=sum+a[i];
                m=sum;
                if(i==len-1&&m<=n)
                {count++;break;}
                else i++;
            }
        }
        System.out.println(count);
    }

}
結果:
input n:45
3
input n:20
2


程式碼編了一下午,足以見當前程式設計能力的欠缺。還得好好練內力啊。當時主要是卡在需要計算當前元素之和上,以及插入新元素向後移動陣列原有元素。後來發現不用插入補丁元素,保留當前元素和就行。


另外就是一個規律的發現,大家可以考慮下為什麼中國剛開始發行錢的時候是1元,2元,5元,10元……的呢?其實原理是一樣的,如果當前陣列元素為空,那麼插入的元素應該是1,2,4,8,16,32……也就是說1,2是必須要有的,然後從此刻開始,下一個元素應補充4,A就變成1,2,4。然後當前3個元素最大可以表示7,所以下一元素應該補充8。同理,1,2,4,8最大可以表示15,所以下一個元素就是16。就是採取這樣的貪心思路,在考慮一下陣列已給出的資料(細節,不影響大局),就可以啦。

相關文章