【万字长文】不学算法你也应该知道的算法知识_你认为不学算法分析与设计一样能够编好程序这一个观点正确吗,并举一个例子加

你可能会说:屁嘞,我不会数据结构与算法,我也照样写程序。我只能说:能说出来这话,一看你就是个新手

你了解什么是数据结构吗?你了解什么是算法吗?不要把它们看得那么高大上,他们的原本定义其实很简单的~~

数据结构:

提一嘴基础知识,在编程语言中,数据是信息的载体,而数据又分为值类型和引用类型。值类型无非就是整数,实数,复数等,而引用类型就是那些数组,字符串,集合图片,音乐等。

有位老哥说过:任何数据都可以使用数据结构表现出来。其实意思就是,数据结构就是存储数据的结构体。

其实数据结构的定义就是这么简单,不要看的太高

算法:

一个程序,有一种书本上的描述:解决一个问题除了要有一个数据结构来表示和组织信息外,还需要一系列步骤来完成问题的解决方案。

当然了,第一个逗号前面的那当然就是数据结构了,那后面的一系列步骤其实说的就是算法。

也可以称为:操作数据结构的方法;或者称为:解决问题的方案

那么看完这两个概念,你是否对数据结构与算法有一个了解了呢?你是否还会说,我不会数据结构与算法也能写程序了呢?

有点模糊也没关系,我来带你看几个例子,你就明白了~~

案例:

例子1 HelloWorld:

HelloWorld也能当数据结构与算法的例子??!没错,没看错,他能!他能!!

java代码:

public class Hello{
  /\*
 在这里Hello和World就是两个数据结构
 将两个数据结构用+拼接起来,就是算法
 \*/
 public static void main(String[] a){
     System.out.println("Hello"+"World"); 
 }
}

Python代码:

print("Hello"+"World")

同理

例子2 两个数字相加:

输入两个数字,输出两个数字的和

Java代码:

public class Hello{
 public static void main(String[] a){
     System.out.println(sumTwo(5,6)); 
 }
 public static int sumTwo(int a, int b){
     return a+b;
 }
}

这里面没有数据结构,只有时间,也有算法,算法就是a+b

Python代码:

def sumTwo(a:int,b:int)->int:
 return a+b

例子3 两数之和(来真的了啊!):

给你一个非空数组,和一个目标值,从数组中找出两个元素使其的和与目标值相同,并返回一个长度为2的数组装这两个值对应的下标,只允许一个元素使用一次

————源于力扣第一题,简单难度

Java代码:

public class Hello{
public static void main(String[] a){
  System.out.println(); 
}
public static TwoSum(int[] nums1, int[] nums2, int target){
  /\*
 最容易想到的,也是没学过系统学习过算法的人的方法
 嵌套循环:
 遍历nums1,再遍历nums2,然后求和,与目标值做判断
 当然,想法很简单,却会出错,因为还要考虑元素只用到一遍
 \*/
  for (int i=0;i<nums.length;i++){
      for (int j=0;j<nums.length;j++){
          if (i!=j){
              if (nums[i]+nums[j]==target){
                  return new int[]{i, j};
              }
          }
      }
  }
  return null;
}
}

这里面就用到了一个数据结构,叫做数组,这里的算法就是将新数组求出来的过程!

Python代码:

class Solution:
 def twoSum(self, nums: List[int], target: int) -> List[int]:
     for i in range(len(nums)):
         for j in range(len(nums)):
             if i==j:
                 continue
             elif nums[i]+nums[j]==target:
                     return [i, j]

当然,例3的方法是很简陋的,更简单的方法还有哈希法和二分法,在这道题中,哈希法的时间复杂度是O(n),二分法的时间复杂度为O(nlogn)

感兴趣的话,可以看看我的这一篇博客:零基础的我刷力扣一周后,总结了点东西

这三个例子大概也能让你对什么是数据结构与算法有一个大致的了解了。那么接着看吧~

二、为什么要学算法

既然知道了算法是什么,那么你知道为什么要学习算法吗?

有人可能会说:因为我想在找工作的时候更有竞争力,更有话语权,所以我来学算法!这个当然没错,面向加薪学习~~

当然了,除了这个,也没什么别的办法能够令人疯狂了吧~~兴趣?有,很少的~

那么为什么公司喜欢会算法的人呢?换句话说,为什么会算法的人会更吃香呢?

因为公司运行你的代码是需要机器的,而机器也是分价钱的,如果你的算法很糟糕,那就会让公司的机器运行起来占用CPU资源多,拟人化一下那就是会很吃力,而且运行你得代码会更耗费时间。

而如果你会算法,甚至算法很好,那么你的算法就会让机器如释重负,甚至跑的更快!

想一想,机器同样的价钱,你会算法能够让机器干更多事,那公司肯定要你啊!别说工资,那一个机器都好贵的。

而算法的出现也是因为先有了问题,之前也说过算法是什么了,就是一个问题的解决方案,所以我们的算法是为了解决问题才出现的。

三、算法的特性

当然一个问题都是可以由多个算法解决的。俗话说,无规矩不成方圆。

那么不同的算法是不是得有相同的规则,或者说相同的特性,才能约束算法,不能任意一种算法就可以解决问题。

打个比方,就用曹冲称象这个例子吧。为了不浪费大家的脑子,我决定就说的简单一点。

现有大象一头,需要知道大象有多重。但是秤太小,无法精准测量。

请你设计一个算法来计算大象的重量。

曹冲的方法:把象放到大船上,在水面所达到的地方做上记号,再让船装载其它东西,称一下这些东西,那么比较下就能知道了。

方法1:我把大象切碎,一块一块量

方法2:造一个超大的秤,专门用来秤大象的重量

你觉得方法1和方法2怎么样?先不急着回答,我们先看看算法的这几个性质。

1. 有穷性

一个算法必须要有一个明确的终止条件来控制处理过程的终止,或者说结束。

什么意思呢?就是你的算法至少要有一个终止条件,或者说能够在特定时间内终止,并计算出结果。要不然你的方法有什么意义呢?

2. 确定性

你的算法的每个步骤都是有明确的目的,不能有别的意思。

就拿上面的例子,你说要把大象切碎,不能切着切着,我还是再造个秤吧。

3. 可行性

你的算法的没一个步骤都是可以被机器或者人执行的。

就像曹冲的方法一样,是切实可行的,而像方法12,则多少有点不切实际了。

4. 正确性

你的算法所计算的结果是能够用来解决这个问题的。

不能说你的算法无法解决问题,那样你的算法也是毫无意义的。

那么,在看完这四个特性后你怎么回答上面的问题呢?

当然,答案我也在特性里面说了出来,还不知道答案的,面壁思过去!

四、算法的分析

那么讲了这么多,我们怎么判断我们的程序是好是坏呢?那就是时间复杂度和空间复杂度。

是不是感觉这两个名词好难理解?没事,他其实也不难。

1. 时间复杂度

所谓时间复杂度就是算法执行的时间。而时间复杂度可以由两种方式:

  • 计算程序实际运行时间
  • 计算程序相对运行时间

我们知道,即使是同一种算法,在不同的编程语言不同的机器,不同的环境索引行的实际时间也是不一样的

所以第一种方式,就不是很银杏化!那么就只能是第二种方法了来判断我们的程序是否得到了优化~~

而时间复杂度又分为三种,最优情况最劣情况平均情况。而这个情况是由问题来决定的~

这三种情况我就不多说啦~看名字就知道了

时间复杂度统一使用O(x)来表示,也是俗称的大O表示法,而时间复杂度的大小与问题有关。

比方说:

  1. 我给你三个数,你把他们三个从小到大排序,时间复杂度是O(3),也可以说是 O(1)
  2. 我给你10**100个数,你把他们从小到大排序,时间复杂度是O(10**100),也可以近似取到O(1)
  3. 我给你几个数,你把他们从小到大排序,时间复杂度为O(n)

那么为什么改了一下题目,时间复杂度就不一样了呢?因为1,2是确定的值,不会受到外部影响而改变,所以只需要循环那么多次,不会改变所以时间复杂度是O(1);而3不一样,他给的值是不确定的,所以需要循环n次,时间复杂度就是O(n)

当然这个也是可以根据问题改变的,那就是对特定的值使用特定的算法。比如二分法,递归的时间复杂度就是O(logn),而O(n)是大于O(logn)的

而如果需要嵌套循环,那么可能是O(n**2)或者O(nlogn)。

常见的时间复杂度按照从小到大的顺序排列有:O(1),O(logn),O(n),O(nlogn),O(n**2),O(2**n),O(n!)

2. 空间复杂度

根据算法在执行过程所使用的存储空间,分为堆区和栈区,当然还有别的区。

而栈区中存放着变量名,堆区中存放着变量名指向的值。这么说可能不好理解,那就画个图吧~~

在这里插入图片描述

诶😱😨叭叭了这么多,好像还没到点上!

稍安勿躁嘛~~

这就来空间复杂度啦~

其实和时间复杂度差不多,我们使用常数,实数,或者对数组,字符串进行原地修改的时候,空间复杂度就是O(1),因为没有开辟新的空间

而如果是新建一个字符串,数组就是需要新开辟一个数组或者字符串空间,所以空间复杂度为O(n)

五、算法

关于一些生活中常见的算法…

这里不讲代码,只讲原理!

1. 贪婪算法

在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法 。

他也叫贪心算法。

举个栗子:

你去超市买东西,买了十三块钱的东西

你拿了一百块钱,给收银员,收银员会给你找零钱

贪婪算法就是:

先找你一张50的,再找你一张20的,再10的,再5的,再1的,再1的

当然这也是一般收银员会选择的方法,通过找给你最少张的纸币,找给你所需要的钱

这就是贪婪算法

贪婪算法所能解决的问题的特性:

  • 该问题至少有一个最优的解决方案。只有这样,才可能为解决问题构造候选方案集合。在前面的例子中候选方案集合就是不同面值的纸币组成的纸币集。
  • 随着问题的求解将建立另外两个集合,-一个集合(假设为集合a)由已经被选出并符合问题要求的候选解组成,另一个集合(假设为集合b)由已经被选出但并不符合问题要求的候选解组成。
  • 集合a最终要包含问题的解答。在集合a中未出现解答时,问题的候选解集合中至少还要剩余一个候选解。

贪婪算法的有点事简单,直观,容易实现,但是缺点也很明显,那就是他会认为当前选择是满足条件的就进行下一个,而不管当前操作是否会对下一操作产生影响。

2. 分治法

- 分治法就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并- 说简单点就是:把一个复杂的问题分成几个简单的问题,如果分的还不够简单,那就接着分,然后再把各个简单的问题解答,最终的答案就是所有简单问题答案的并集

举个栗子:

给你一个有序数组和一个目标值,请找出这个元素的下标

我们使用二分查找法

Java代码:

public class ErFen{
 public static void main(String[] a){

 }
 public static int Defg(int[] nums, int target){
     int start = 0;
     int end = 0;
     int mid = 0;
     for (int i=0;i<nums.lenrth;i++){
         mid = (start+end)/2;
         if (nums[mid]>target) end = mid;
         else start = mid+1;
     }
     return mid;
 }
}

Python代码:

def Defg(nums:list, target:int)->int:
 start = 0
 end = 0
 mid = 0
 for i in range(len(nums)):
     mid = (start + end) //2
     if nums[mid]>target: end = mid
     else: start = mid
 return mid

看不懂?没关系,看这是什么!!!大宝贝!——LeetCode刷题278-简单-第一个错误版本

分治法所能解决的问题的特性:

  • 整个问题可以分解为两个或者多个较小的问题
  • 对每个子问题的求解类似于对整个问题的求解
  • 如果子问题的规模或者难度仍旧很大,那就继续使用分治法
    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以点击这里获取
长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
[外链图片转存中…(img-RiSl5tjl-1714770315791)]
[外链图片转存中…(img-VEcZkXFW-1714770315792)]
[外链图片转存中…(img-6PjIIAvO-1714770315792)]
[外链图片转存中…(img-YDOR9ggh-1714770315793)]
[外链图片转存中…(img-SCwy0GIQ-1714770315794)]
[外链图片转存中…(img-IIdIkwut-1714770315794)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以点击这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值