1. 程式人生 > >【精選】JAVA入門演算法題(一)

【精選】JAVA入門演算法題(一)

跌倒了,一定要爬起來。不爬起來,別人會看不起你,你也會失去機會。

1.題目:打印出楊輝三角形(要求打印出10行)

什麼是楊輝三角呢?下面這個就是

楊輝三角最大的特性就是每個數字都是該數字肩上的兩個數字之和,這道題經常在學習二維陣列和迴圈控制中出現

我們可以假設吧這些數存在一個二維陣列中,那麼ints[i][j]=ints[i-1][j-1]+ints[i-1][j];我們可以很容易使用for迴圈加二維陣列實現它

int[][] ints=new int[10][10];
        for (int i=0;i<10;i++){
            for (int j=0;j<=i;j++){
                if (i-1<0||j-1<0){
                    ints[i][j]=1;
                }else {
                    ints[i][j]=ints[i-1][j-1]+ints[i-1][j];
                }
                System.out.print(ints[i][j]+" ");
            }
            System.out.println();
        }

2.題目:有一對兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,問每個月的兔子總數為多少?

對於這種一開始看可能沒思路的題你可以採取先把前幾個數字寫出來,然後研究其規律,最後程式設計實現

那麼我們把前10個月的數字寫出來:1 1 2 3 4 8  13 21 34 55

通過觀察發現這個數列的規律為每個數字為前兩位數字之和,這不就是斐波那契數列嗎?(高中講的)

那我們便可以定義三個變數分別表示一月份的兔子、二月份的兔子、三月份的兔子,使用for迴圈不斷輸出每個月的兔子數量

另外我們還要定義一個變數用於交換值

每次迴圈時,先使用額外變數儲存一月份的兔子數,該月的一月兔子數等於二月份兔子長到三月份生的一窩加上原來已經就是三月份的兔子生的一窩

三月份的兔子數等於二月份的兔子長到三月份了加上原來就是三月份的兔子

二月份的兔子等於上個月一月份的兔子

總數就是三個變數之和

int count=1;
        int oneMonth=1;
        int twoMonth=0;
        int threeMonth=0;
        int cache=0;
        for (int i=0;i<30;i++){
            System.out.println("月份:"+(i+1)+" 總數:"+count+" 一月:"+oneMonth+" 二月:"+twoMonth+" 三月:"+threeMonth);
            cache=oneMonth;
            oneMonth=twoMonth+threeMonth;
            threeMonth=twoMonth+threeMonth;
            twoMonth=cache;
            count=oneMonth+twoMonth+threeMonth;
        }

那還有一種思路就是把兩個月的兔子看成一輪,每個月的數量等於前兩個月份之和,一次算出來兩個月分別的兔子數量

long s1,s2;// 定義這個月和下個月兔子的數量
        s1 = 1;  //第一個月為1對
        s2 = 1;  //第二個月為1對
        int i=1;  //定義一個控制變數
        int m=30;  // 月份數
        //while迴圈
        while(true){
            //第一個月和第二個月兔子的數量都為1對
            if(i==1||i==2){
                System.out.println(i+" month: "+s1);
                i++; // 控制變數 i 加1
            }
            // i 大於3並且小於我們需要檢視的月份
            else if(i<m){
                s1 = s1+s2;
                s2 = s1+s2;
                System.out.println(i+" month: "+s1);
                i++;//月份加1
                System.out.println(i+ " month: "+s2);
                i++; //月份加1
            }else{
                break;//不符合條件就退出
            }

        }

我們還可以利用java自帶的資料結構來完成這件事

LinkedList<Integer> integerList=new LinkedList<>();
        for (int i=0;i<30;i++){
            if (i<2){
                integerList.add(1);
                System.out.println("月份:"+(i+1)+" 兔子總數:"+integerList.getLast());
            }else {
                integerList.add(integerList.getLast()+integerList.get(integerList.size()-2));
                System.out.println("月份:"+(i+1)+" 兔子總數:"+integerList.getLast());
            }
        }

3.題目:判斷101-200之間有多少個素數,並輸出所有素數。

判斷素數的方法:用一個數分別去除2到sqrt(這個數),如果能被整除,則表明此數不是素數,反之是素數。

遇到這種題就直接暴力for迴圈,定義個boolen判斷是不是素數

for (int i=101;i<=200;i++){
            boolean isPrimeNumber=true;
            for (int j=2;j<i;j++){
                if (i%j==0){
                    isPrimeNumber=false;
                    break;
                }
            }
            if (isPrimeNumber){
                System.out.println(i);
            }
        }

有一種巧妙的辦法可以不用定義boolen變數作為標誌,我們只需要把內層玄幻的j定義在外層,這樣如果i等於j說明迴圈走完了,就可以判斷它是一個素數

 int j=0;
        for (int i=101;i<=200;i++){
            for (j=2;j<i;j++){
                if (i%j==0){
                    break;
                }
            }
            if (j==i){
                System.out.println(j);
            }
        }

在這些優化之後我們還可以借用數學的幫助,凡是一個數開方後的數的素數都是原來那個數的素數,至於最後的加一是因為迴圈是從2開始的,1是任何數的因數

 int j=0;
        int k=0;
        for (int i=101;i<=200;i++){
            k=(int)sqrt(i+1);
            for (j=2;j<=k;j++){
                if (i%j==0){
                    break;
                }
            }
            if (j==k+1){
                System.out.println(i);
            }
        }

4.題目:將一個正整數分解質因數。

例如:輸入90,打印出90=2*3*3*5。

其實這道題就相當於找素數的升級版,找到給定範圍內幾個素數的想乘結果等於它本身

做這種題我們很容易想到遞迴,不斷找素數,不斷縮小範圍

static List<Integer> integerList=new ArrayList<>();
private static void Method1() {
        Scanner scanner=new Scanner(System.in);
        int number=scanner.nextInt();
        getPrimeFactor(number);
        System.out.println(integerList);
    }

    private static void getPrimeFactor(int number) {
        for (int i=2;i<=number;i++){
            if (number%i==0){
                integerList.add(i);
                getPrimeFactor(number/i);
                break;
            }
        }
    }

我們可以將其轉換成while迴圈

 Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k=2;
        System.out.print(n+"=");//輸出第一步格式
        while(k<=n){//初值k為2,n為輸入的數字,在程式執行的過程中k漸漸變大(k++),n漸漸變小(n/k)
            if(k==n){//當n和k相等的時候,就直接輸出n的值(此時輸出k也行,因為n==k)
                System.out.println(n);
                break;
            } else if(n%k==0){
                System.out.print(k+"*");//如果n <> k,但n能被k整除,則應打印出k的值
                n = n/k;//n除以k的商,作為新的正整數你n
            }else{
                k++;//如果n不能被k整除,則用k+1作為k的值
            }
        }