算法入门级题目

0. 算法是什么

算法是针对具体的问题设计解决问题的具体流程,并且有评价该处理流程的可量化的指标。


1. 算法分类

算法也有很多的分类,简单来说的话,可以分为明确具体的流程,和明确尝试的具体的流程两类。

  • 明确具体的流程(a+b)
  • 明确尝试的具体流程(a的所有的素数)

2. 入门级别的算法题目

题目一:1!+2!+3!+...+n! 的结果

  • 算法思路:
    1! = 1
    2! = 1 2
    3! = 1 2 3
    ......
    n! = 1 2 3 ... n
    所以,1!+2!+3!+...+n! = 1 + 1 2 + 1 2 3 + ... + 1 2 3 ... n
    此时,我们假设每一个数字是 i, 一共有n个数,我们分别求得i的阶乘,然后想加起来。循环n遍即可得。
    代码如下:
  public static void factorial1(int n){
        int sum = 0;
//从1~n个数
        for(int i = 1; i <= n; i++){
            int curSum = 1;
//对每个i的数字求其阶乘,1 * 2  * ...i 
            for(int j = 1; j <= i; j++){
                curSum *= j;
            }
            sum += curSum;
        }
        System.out.println(sum);
    }

这个算法思路解决了我们的问题,那我们看一下这个代码,有两个for循环,复杂度偏高,有没有再优化一下的思路呢。我们观察,后一个的阶乘是建立在前一个阶乘的结果之上的。

  • 优化思路:
    2! = 1! 2
    3! = 2! 3
    ...
    n! = (n-1)! n
    那么我们就不必重复去求得前一个数的阶乘了,保存下来即可。
    优化代码:
public static void factorial(int n){
        int sum = 0;
        int facNum = 1;
        for (int i = 1; i <= n; i++){
            facNum *= i;
            sum += facNum;
        }
        System.out.println(sum);
    }

这个代码可以清楚地看到我们少了一个for循环,复杂度大大下降。
至此,求阶乘的问题已经解决了,很多时候,我们拿到问题时,都不能一下子想到那个最优解,没关系,我们可以慢慢来,一步步分析,先做到有那个最不优的算法,然后再观察,看是否可以进一步优化即可。

题目二:选择排序

算法思路:
在0~n-1位置找最小值,交换放在0号位置;
在1~n-1位置找最小值,交换放在1号位置;
...
在n-2~n-1位置找最小值,交换放在n-2位置;
每轮都选出最小值,然后放在相应的位置。


image.png

image.png

最终,这个数组就会被每轮选择最小值然后交换,成为从小到大的有序数组。

代码如下:

   public static void selectSort(int[] arr){

        if(null == arr || arr.length < 2){
            return;
        }

        for(int i = 0; i < arr.length -1 ; i++){
            int minValueIndex = i;
            for(int j = i + 1; j < arr.length; j++){
                minValueIndex = arr[j] < arr[minValueIndex] ? j : minValueIndex;
            }
            swap(arr, i, minValueIndex);
        }
    }

题目三:冒泡排序

算法思路:两两比较,较大的数向右移。
在0~n-1 边比较边右移,将大的数向右沉;(最大的数在n-1位置)
在0~n-2 边比较边右移... (第二大的数在n-2位置)
...


image.png

image.png

一轮轮的比较交换比较交换后,数组就会成为从小到大的有序数组。
代码如下:

  public static void bubbleSort(int[] arr){
        if(null == arr || arr.length <2){
            return;
        }

        for(int end = arr.length-1; end >= 0; end --){
            for(int start = 0; start < end; start ++){
                if(arr[start] > arr[start+1]){
                    swap(arr, start, start+1);
                }
            }
        }
    }

题目四:插入排序

算法思路:局部形成有序,来一个数,进行从右向左的比较,将它插入在合适的位置。
在0位置有序;
在0~1位置有序;
在0~2位置有序;
...


image.png

代码如下:

public static void insertSort(int[] arr){
        if(null == arr || arr.length < 2){
            return;
        }

        for(int i = 1; i < arr.length; i++){
            for(int j = i-1; j >= 0 && arr[j] > arr[j+1]; j--){
                swap(arr, j, j+1);
            }
        }
    }

3. 总结

算法就是解决问题的处理流程。
我们可以看到选择排序,冒泡排序,插入排序都是复杂度为o(),且频繁交换或者频繁比较,说明这三个排序并不算是性能最好的排序,但是它们易于理解和代码编写,算是新手入门的最佳例题。


你可能感兴趣的:(算法入门级题目)