十道簡單算法題

前言

最近在回顧之前使用C寫過的數據結構和算法的東西,發現本身的算法和數據結構是真的薄弱,如今用Java改寫一下,重溫一下。java

只能說慢慢積累吧~下面的題目難度都是簡單的,算法的大佬可直接忽略這篇文章了~入門或者算法薄弱的同窗可參考一下~程序員

不少與排序相關的小算法(合併數組、獲取數字每位值的和),我都沒有寫下來了,由於只要會了歸併排序(合併數組),會了桶排序(獲取數字每位的值),這些都不成問題了。若是還不太熟悉八大基礎排序的同窗可看:【八大基礎排序總結算法

因爲篇幅問題,每篇寫十道吧~數組

若是有錯的地方,或者有更好的實現,更恰當的理解方式但願你們不吝在評論區留言哦~你們多多交流微信

十道簡單算法題

題目的總覽

  1. 1-n階乘之和
  2. 獲取二維數組每列最小的值
  3. 求"1!+4!(2的平方)+9!(3的平方)+...+n的值
  4. 數組對角線元素之和
  5. 打印楊輝三角形
  6. 猴子吃桃子問題
  7. 計算單詞的個數
  8. 判斷字母是否徹底同樣
  9. 判斷一個數是否是2的某次方
  10. 判斷一個數字是否是ugly number

1、1-n階乘之和

1-n階乘之和怎麼算?數據結構

  • 1的階乘是1
  • 2的階乘是1*2
  • 3的階乘是1*2*3
  • 4的階乘是1*2*3*4
  • .........

如今咱們要求這些階乘的和。思路:數據結構和算法

  • 3階乘的和其實上就是2階乘的和+3的階乘
  • 4階乘的和其實上就是3階乘的和+4的階乘
  • .......
/** * 1-n的階乘之和 */
    public static void Factorial(int n) {

        //總和
        double sum = 0;

        //階乘值,初始化爲1
        double factorial = 1;

        for (int i = 1; i <= n; i++) {

            factorial = factorial * i;


            sum = (int) (sum + factorial);

        }

        System.out.println("公衆號:Java3y" + " " + sum);

    }
複製代碼

2、獲取二維數組每列最小的值

獲取二維數組每列最小的值spa

思路:遍歷列,再遍歷列中行3d

咱們通常操做數組都是從行開始,再到列的。此次要求的是每列的最小值,所以須要在內部for循環遍歷的是行code

/** * 求出二維數組每列的最小值 */
    public static void minArray() {


        //二維數組
        int[][] arrays = {
            {23, 106, 8, 234},
            {25, 9, 73, 19},
            {56, 25, 67, 137}
        };


        //獲取列數
        int maxColLength = arrays[0].length;



        //使用一個數組來裝載每列最小的值
        int[] minArray = new int[maxColLength];


        //控制列數
        for (int i = 0; i < maxColLength; i++) {

            //假設每列的第一個元素是最小的
            int min = arrays[0][i];

            //控制行數
            for (int j = 1; j < arrays.length; j++) {


                //找到最小值
                if (arrays[j][i] < min) {
                    min = arrays[j][i];
                }
            }

            //賦值給裝載每列最小的值的數組
            minArray[i] = min;
        }


        System.out.println("公衆號:Java3y" + " " + minArray);

    }


複製代碼

3、求"1!+4!(2的平方)+9!(3的平方)+...+n的值

求"1!+4!(2的平方)+9!(3的平方)的值

思路:先求平方,後求階乘,最後相加便可~

/** * 求"1!+4!(2的平方)+9!(3的平方)+...+n的值 */
    public static void calculate() {

        double sum = 0;

        for (int i = 1; i <= 3; i++) {

            //獲得平方數
            int square = i * i;

            //階乘值,從1開始
            double factorial = 1;

            //求階乘
            for (int j = 1; j <= square; j++) {
                factorial = factorial * j;
            }

            sum = sum + factorial;

        }

        System.out.println("公衆號:Java3y" + " " + sum);
        
    }
複製代碼

4、數組對角線元素之和

數組對角線元素之和

思路:

  • 只要行和列相等,便是對角線的元素
/** * 數組對角線之和 */
    public static void arraySum() {

        int[][] arrays = {
                {23, 106, 8, 234},
                {25, 9, 73, 19},
                {56, 25, 67, 137},
                {33, 22, 11, 44},
        };

        //和
        int sum = 0;

        for (int i = 0; i < arrays.length; i++) {

            for (int j = 0; j < arrays[i].length; j++) {

                if (i == j) {

                    sum = sum + arrays[i][j];

                }
            }
        }


        System.out.println("公衆號:Java3y" + sum);
        
    }
複製代碼

5、打印楊輝三角形

楊輝三角形

楊輝三角形長的是這個樣子:

ps:圖片來源網上,侵刪~

規律:

  • 每行的第一個和最後一個都是1
    • 進一步推算:第1列所有爲1,第一行全都是1,當列數等於行數爲1
  • 當前值等於頭上的值加頭上的左邊的值
  • 第一行一列,第二行兩列,第三行三列.......

代碼實現:

/** * 打印楊輝三角形 */
    public static void PascalTriangle() {


        //打印十行的楊輝三角形
        int[][] arrays = new int[10][];


        //行數
        for (int i = 0; i < arrays.length; i++) {


            //初始化第二層的大小
            arrays[i] = new int[i + 1];

            //列數
            for (int j = 0; j <= i; j++) {

                //是第一列,第一行,行數等於列數,那麼統統爲1
                if (i == 0 || j == 0 || j == i) {
                    arrays[i][j] = 1;
                } else {

                    //當前值等於頭上的值+頭上左邊的值
                    arrays[i][j] = arrays[i - 1][j] + arrays[i - 1][j - 1];
                }

            }
        }

        System.out.println("公衆號:Java3y" + "-------------------------------");

        for (int[] array : arrays) {
            for (int value : array) {
                System.out.print(value + "\t");
            }
            System.out.println();

        }


        System.out.println("公衆號:Java3y" + "-------------------------------");


    }
複製代碼

結果:

6、猴子吃桃子問題

猴子摘下了n個桃子,當天吃掉一半多一個,次日也是吃掉剩下桃子的一半多一個,到了第十天,桃子只剩下了1個。問:猴子第一天摘了多少個桃子

思路:

  • 假設當天有n個桃子,它是前一天桃子的一半少1個,f(n - 1) = f(n)/2 - 1,
  • 咱們就能夠推出當天桃子的個數:根據遞推公式:f(n) = 2 * f(n - 1) + 2

用遞歸和循環均可解決:

遞歸方式:

/** * 猴子吃桃問題 * @param x 天數 */
    public static int monkeyQue(int x) {

        if (x <= 0) {
            return 0;

        } else if (x == 1) {
            return 1;

        } else {
            return 2 * monkeyQue(x - 1) + 2;
        }

    }
複製代碼

循環方式:

int x = 1;
        for (int i = 1; i <= 9; i++) {
            x = (x + 1) * 2;
		}
複製代碼

結果:

7、計算單詞的個數

輸入一段字符,計算出裏面單詞的個數,單詞之間用空格隔開 ,一個空格隔開,就表明着一個單詞了

思路:

  • 把字符遍歷一遍,累計由空格串轉換爲非空格串的次數,次數就是單詞的個數
  • 定義一個標誌性變量flag,0表示的是空格狀態,1表示的是非空格狀態
/** * 輸入一段字符,計算出裏面單詞的個數 * * @param str 一段文字 */
    public static int countWord(String str) {


        // 0 表示空格狀態,1 表示非空格狀態
        int flag = 0;

        // 單詞次數
        int num = 0;


        for (int i = 0; i < str.length(); i++) {

            if (String.valueOf(str.charAt(i)).equals(" ") ) {
                flag = 0;
            } else if (flag == 0) {
                num++;
                flag = 1;
            }

        }

        return num ;

    }

複製代碼

結果:

8、判斷字母是否徹底同樣

給定兩個字符串s和t,判斷這兩個字符串中的字母是否是徹底同樣(順序能夠不同)

思路:

  • 遍歷這兩個字符串,用每一個字符減去'a',將其分別存入到數組中去,隨後看這兩個數組是否相等便可

要點:

  • 'c'-'a'=2便可計算出存儲的位置,若是有多個,則+1便可,後面咱們來比較數組大小

代碼實現:

/** * 給定兩個字符串s和t,判斷這兩個字符串中的字母是否是徹底同樣(順序能夠不同) */
    public static void isAnagram() {

        //分別存儲字符串的字符
        char[] array1 = new char[26];
        char[] array2 = new char[26];


        String s1 = "pleasefollowthewechatpublicnumber";
        String s2 = "pleowcnumberthewechatpubliasefoll";


        for (int i = 0; i < s1.length(); i++) {
            char value = s1.charAt(i);

            // 算出要存儲的位置
            int index = value - 'a';

            array1[index]++;
        }

        for (int i = 0; i < s2.length(); i++) {
            char value = s2.charAt(i);

            // 算出要存儲的位置
            int index = value - 'a';

            array2[index]++;
        }

        for (int i = 0; i < 26; i++) {
            if (array1[i] != array2[i]) {
                System.out.println("不相同");
                return;
            }
        }

        System.out.println("相同");

    }

複製代碼

結果:

9、判斷一個數是否是2的某次方

判斷一個數是否是2的某次方

思路:

  • 除2取餘數,直至餘數不爲0【針對2的倍數這種狀況】,看是否是等於1就能夠判斷是否是2的某次方了
/** * 判斷是不是2的某次方 */
    public static void isPowerOfTwo() {

        int num = 3;

        if (num == 0) {
            System.out.println("不是");
        }

        while (num % 2 == 0) {
            num = num / 2;
        }

        if (num == 1) {
            System.out.println("是");
        } else {
            System.out.println("不是");

        }

    }

複製代碼

結果:

這題還有另外一種解決方式,就是位運算:

  • 2的n次方都有一個特色,二進制都是1000000
  • 若是 **2的n次方的二進制-1和2的n次方二進制作按位與運算,那麼得出的結果確定是0 **
if(num <= 0){
        System.out.println("不是");
    }
    else if(num == 1){
        System.out.println("是");
    }
    else{
        if( (num & (num-1) ) == 0){
            System.out.println("是");
        }
        else{
            System.out.println("不是");
        }
    }
複製代碼

10、判斷一個數字是否是ugly number

判斷一個數字是否是ugly number(分解出來的質因數只有二、三、5這3個數字)

思路:

  • 若是是由2,3,5組成的,那麼這個數不斷除以2,3,5,最後得出的是1,這個數就是純粹用2,3,5組成的
    • 跟以前判斷該數是否2的某次方是同樣的思路~

代碼:

/** * 判斷一個數字是否是ugly number(分解出來的質因數只有二、三、5這3個數字) * @param num */
    public static void isUgly(int num) {
        if (num <= 0) {
            System.out.println("不是");
        } else {
            while (num % 2 == 0) {
                num = num / 2;
            }
            while (num % 3 == 0) {
                num = num / 3;
            }
            while (num % 5 == 0) {
                num = num / 5;
            }
            if (num == 1) {
                System.out.println("是");

            } else {
                System.out.println("是");

            }
        }
    }
複製代碼

結果:

總結

沒錯,你沒看錯,簡單的小算法也要總結!

其實我以爲這些比較簡單的算法是有"套路"可言的,你若是知道它的套路,你就很容易想得出來,若是你不知道它的套路,那麼極可能就不會作了(沒思路)。

積累了必定的"套路"之後,咱們就能夠根據經驗來推斷,揣摩算法題怎麼作了。

舉個很簡單的例子:

  • 乘法是在加法的基礎之上的,那乘法咱們是怎麼學的?**背(積累)**出來的,9*9乘法表誰沒背過?好比看到2+2+2+2+2,會了乘法(套路)之後,誰還會慢慢加上去。看見了5個2,就直接得出2*5

  1. 1-n階乘之和
    • 求n的階乘就用1*2*3*4*...n,實際上就是一個循環的過程,求和就套個sum變量便可!
  2. 獲取二維數組每列最小的值
    • 外層循環控制列數,內層循環控制行數,這就是遍歷每列的方法~
  3. 求"1!+4!(2的平方)+9!(3的平方)+...+n的值
    • 先求平方,再求階乘,最後套個sum變量
  4. 數組對角線元素之和
    • 行和列的位置相等,便是對角線上的元素
  5. 打印楊輝三角形
    • 找出楊輝三角形的規律:第一行、第一列和列值等於行值時上的元素都是1,其他的都是頭上的值加頭上的左邊的值
  6. 猴子吃桃子問題
    • 根據條件,咱們能夠推算出前一天桃子,進而推出當天桃子(規律)。猴子都是在相等的條件(剩下桃子的一半多一個),所以就應該想到循環或者遞歸
  7. 計算單詞的個數
    • 利用每一個單詞間會有個空格的規律,用變量來記住這個狀態(字母與空格)的轉換,便可計算出單詞的個數!
  8. 判斷字母是否徹底同樣
    • 將每一個字母都分別裝載到數組裏面去,'c-a'就是字母c數組的位置了(也就是2)。因爲字母出現的次數不惟一,所以咱們比較的是數組的值(若是出現了兩次,那麼值爲2,若是出現了3次,那麼值爲3)。只要用於裝載兩個數組的值都吻合,那麼字母就是同樣!
  9. 判斷一個數是否是2的某次方
    • 最佳方案:2的某次方在二進制都有個特色:10000(n個0)--->ps:程序員的整數~..........那麼比這個數少一位的二進制確定是01111,它倆作&運算,那麼確定爲0。用這個特性就很是好判斷該數是不是2的某次方了
    • 次方案:2的某次方的數不斷縮小(只要number % 2 == 0就能夠縮小,每次number / 2),最後的商必然是1。
  10. 判斷一個數字是否是ugly number
    • 分解出來的質因數只有二、三、5這3個數字,這題其實就是判斷該數是否爲2的某次方的升級版。將這個數不斷縮小(只要number%2||%3||%5==0,每次number / 2 | / 3 /5),最後的商必然是1

若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:Java3y

相關文章
相關標籤/搜索