算法入门篇(一)

1.什么是算法?为什么要学习算法?
它是一组具有良好定义的规则,可以有效地解决一些计算方面的问题。如排序,计算最小或是最佳路径距离之类的。
因为算法牛逼,想成为大佬,所有要学。

比如: 判定一个数是否是2的整数次幂?
 2 4 8 16 32 64 128 256。。。
a. 取模求余法(最常见的)
b. 由2,联想到二进制;进行逻辑运算 , 找找规律
        1--> 01     3--> 011   
        2--> 10     4--> 100
   1&2 == 0   3&4 == 0   (很明显可以) --> 推出 N&(N-1) == 0
   1|2   ==11  3|4   ==111 (不行)
        7--> 0111    15--> 01111
        8--> 1000    16--> 10000

二进制位运算:
     按位与运算:   2&6 == 2
   
按位移运算: 1  < < 2 == 4  相当于:  n<<x相当于 n*2^x
 
2.时间复杂度和空间复杂度
 
概念:  时间复杂度是指执行这个算法所需要的计算工作量;而空间复杂度是指执行这个算法所需要的内存空间。
时间复杂度列举:
    int a=0;   O(1)
    int b = a + 1;   O(1)
    for(int i=0;1<5000;i++){xx}     O(5000) =>  O(1)
   常量型时间复杂度 统一为 O(1)。
 
   int n; //未知的
   for(int i=0;i<n;i++){xx}  O(n)
   线性型。
 
  int a=1,n;
  while(a < n){
    a = a * 2;
=> 2 4 8 16 32...
}
相当于: 2 ^ a =n; => a = log2^n;  应该有人会觉得log的底数是10,而我们这边底数是2,但在算法里面,我们只会用数学的方法把n无限大去比较,所以不管底数是多少,算法的时间复杂度的增长与处理数据多少的增长的关系是一样的。套用规则,这段代码执行次数logn + 1,保留高阶项,去除高阶常数,所以时间复杂度是O(logn)。 -->对数型
 
for(int i=0;i<n;i++){
    while(a < n){
    a = a * 2;
   }
}  => nlog(n)
 
for(int i=0;i<n;i++){ O(n)
    for(int i=0;i<n;i++){O(n)
 }
}  ==> O(n^2)
 
for(int i=1; i<=n; i++){ 
    for(int j=i ;i<=n; i++){
 }
i=1 => 1
i=2 => 2
....
i=n-1 => n-1
i=n => n
即: 1+2+3+....+(n-1)+n 等差数列 => n(n+1)/2 => n^2/2 + n/2 =>(n很大时,常数可以忽略) 为O(n^2)
 
空间复杂度:(表示占用的内存)
int []a = new int[n]; O(n)
List<String> list = new ArrayList<>();

3.常见的数据结构
1.List 
    =>Array(ArrayList & Vector单线程安全)   查询快,有下标
         链表(LinkedList)插入快,有next结点可直接指向
2.Set 
    =>HashSet 去重,去重后的顺序和插入顺序不一致
         TreeSet  排序,排序后的顺序和插入顺序不一致,底层红黑树
          LinkedHashSet  链表实现,记录顺序,保证插入顺序和输出顺序一致
3. Map 
    => HashMap 键值对,非线程安全
          TreeMap 排序,底层红黑树
          ConcurrentHashMap 线程安全
4.Queue(FIFO) 
    => 场景:等待、排队、消息队列、优先队列等
          PriorityQueue 优先队列
          ArrayBlockingQueue 基于数组的阻塞队列
          LinkedBlockingQueue 基于链表的阻塞队列,也是无界队列 
          DelayQueue 延迟队列
          

猜你喜欢

转载自www.cnblogs.com/flyinglion/p/11087142.html