算法笔记

算法的学习从排序开始。
首先,了解几个概念。
时间复杂度:算法要目的就是为了更快,更省的解决一个问题。而鉴定算法的快慢就要看他的时间复杂度。
空间复杂度:算法可能消耗的内存空间的体现。
原地排序算法:排序过程中没有申请多余空间,在原地执行。这样空间复杂度就较低。
稳定排序算法:两个值相等的情况时,位置不变。

冒泡排序:从第一个位置开始,与后面的位置比较,如果后面的值更小,则交换位置(从小到大排),然后从下一个位置起,和后面的比较。

 //冒泡排序
    private static int[] maoPaoSort(int[] a){
        if(a == null || a.length< 1) return null;
        for( int i = 0;i < a.length;i++ ){
            boolean flag = true;
            for(int j = 0;j < a.length-i-1;j++){
                if(a[j] > a[j+1]){
                    flag=false;
                    int temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
            if(flag) break;
        }
        return a;
    }
    时间复杂度:经历了两次循环,所以为O(n^2)

优化:如果在某次冒泡后,已经是有序的了,那之后的遍历操作就是多余的了。
插入排序:将一个数组划分为已排序区间,未排序区间。最开始已排序区间只有一个值,从未排序区间取值出来,去已排序区间查找,找到相应的下标,然后将之后的元素往后移动一位,再将值插入到相应位置。

 //插入排序
    private static int[] insertSort(int[] a){
        if(a == null || a.length< 1) return null;
        for(int i =1;i < a.length;i++){
            int value = a[i];
            int j = i - 1;
            for(;j >= 0;j--){
                if(a[j] > value){
                    a[j+1] = a[j];
                } else{
                    break;
                }
            }
            a[j+1] = value;
        }
        return a;
    }

时间复杂度:O(n^2)
冒泡排序的数值交换操作要进行3次赋值语句,而插入排序数值交换只有一句。所以插入排序用的比冒泡多。

选择排序:也有两个区间,已排序区间和未排序区间。每次从未排序区间取最小值插入到已排序区间里去。(非稳定排序算法)

//选择排序
    private static int[] selectSort(int[] a){
        if(a == null || a.length< 1) return null;
        for(int i = 0;i<a.length;i++){
            int min = a[i];//最小值
            int b = i;//最小值的下标
            for(int j = a.length-1;j>i;j--){
                if(a[j]<min){
                    min = a[j];
                    b=j;
                }
            }
            a[b] = a[i];
            a[i] = min;
        }
        return a;
    }

时间复杂度:O(n^2)
然后就是更加高级一点的排序算法,要先了解一个思想。
递归:将一个问题分成小问题解决,关键在于递归公式,临界条件。
容易出现的问题有:堆栈溢出,重复计算,函数调用耗时多,空间复杂度高。
堆栈溢出解决方案:设置一个全局变量控制递归的深度。
重复计算:利用某种数据结构存储递归的值,再第二次计算时直接取出来

归并排序:sort(a,p,r) 将a数组p到r的数据排序。这样a[n]排序是 sort(a,o,n-1)
p=(0+n-1)/2 sort(a,0,p);sort(a,p+1,n-1)(非原地排序算法) 核心思想是递归

快速排序(快排):选择数组中的一个数据为分区点,比这个小的数据放左边,比这个大的放右边。然后对左右的在进行一次分区,知道最后只剩一。 核心思想是递归
快排最坏时间复杂度为O(n^2)
避免这个的方法:
三数取中法:取头尾中间点的值,取中间的为区分点。
随机法:随机取一个值。

桶排序:将数据均匀的分成几个桶,把桶范围内的数据塞到对应的桶里去。然后对桶内数据进行快排,然后把桶连接起来。
0-100的数据
分成 0-20 20-40 40-60 -60-80 80-100

计数排序:一种特殊的桶排序,使用于层次较少的情况。比如分数有100分,分成100个桶,将对应的学生分数,放到对应的桶里,实现排序。

基数排序:比如1万条手机号码排序。先比较最后一位,再比较前一位,进行11次比较。长度不一的情况在后面补0,变成长度一致的。

然后是其他比较基础的算法
贪心算法:针对一组数据,我们定义了限制值和期望值,希望从中选出几个数据,在满足限制值的情况下,期望值最大。
分治算法:分而治之,将问题划分成小问题解决,然后合并。(递归)
回溯算法:我们枚举所有的解,找到满足期望的解。为了有规律地枚举所有可能的解,避免遗漏和重复,我们把问题求解的过程分为多个阶段。每个阶段,我们都会面对一个岔路口,我们先随意选一条路走,当发现这条路走不通的时候(不符合期望的解),就回退到上一个岔路口,另选一种
走法继续走。
动态规划

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值