一、前言

之前一直想学习数据结构与算法,因为一直听说这个很重要嘛,还有力扣这个网站那也是神交已久啊~~

但是又不敢接触,因为恐惧嘛,害怕学不会,害怕被吊打~~~~~

后来遇到了一个大佬,算法大佬,超强的!

————英雄哪里出来

我跟他聊了我的情况,他就推荐我开始刷力扣,刷简单的,通过率高的,先培养习惯,兴趣,信心。然后我就开始了!

小结计划

这是我第一篇小结
以后每周一会做一篇周结
每月月结,同时删除周结

二、相关知识

1. 时间复杂度O()

算法的目的就是为了提高程序的效率,而在优化了程序后,表现最突出的就是程序的运行时间。

那么测试我们的程序是否跑的更快了,难道掐秒计算吗?

举个例子:

程序优化完后,运行一结束。诶诶,快停,记录时间!!看看快了没!

而这个时间,为实际时间,也可以说是绝对时间,但是这个时间能被很多因素影响

而这个因素就有很多了,硬件,软件,系统等…

所以进引入了相对时间的计时方法,也就是时间复杂度,来判断我们的程序是否得到了优化

规定,一段程序的时间由时间复杂度来表示。

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

比如:我们将某个正在军训的班级拉出来一排,一排五个人,让他们从左到右依次报数(从1开始)
用这个数来代表他们本来的名字,作为代号
而我们需要找一个叫做张三的人

不过我们不能大声问谁是张三,只能根据代号挨个去问
如果张三的代号为1,那么我们只需要寻找一次就可以
如果为3那么我们需要寻找3次
如果为5或者张三不在这一排,我们就必须查找5次才能得到结果

而这个第一种情况就是最优情况,为O(1),第三种情况为最劣情况,也就是O(n)

通常使用最劣情况来表示一个程序的最终情况,也就是O()

一个简单的赋值语句,判断语句的时间复杂度为O(1),而不管你这个语句有多长,只要他是切实能写出来的次数,都是O(1)

循环语句根据循环的次数的变化而分为O(1),O(N),上面说过O(1)那么O(n)就是循环的次数随着题目或者问题的改变而改变的,就属于O(n)

而判断整个程序时间复杂度的方法为,以时间复杂度最高的为主:也就是说,就算你赋值了1000000个变量,而循环结果是随时间变化的,那么你的程序的时间复杂度为:O(n)

因为随着循环次数的增加,也就是n->无穷大,你的变量数目,也会相对于n来说越来越小。

所以可以忽略不计,为O(1)*O(n)==O(n)

常见的时间复杂度:O(1),O(logn),O(n),O(nlogn),O(n*2),O(2**n)O(n!)

按照从小到大的顺序排列

2. 空间复杂度O()

空间复杂度也具有相同的概念,只是有些地方变得不太一样了

如果说时间还能掐秒计算时间,那么占用空间就没那么好计算了,难不成,你去看看代码多少航,行多的占用内存就大吗?这也不是,有的代码很少,但是需要占用的内存多,有的代码看着很多,但是占用内存很小

空间复杂度是想对占用空间,比如说,你的程序创建100个变量接收了100个数字,字符串,在空间复杂度里面属于O(1),而你创建一个数组,哈希表,栈等就是O(n)

三、刷题小结

自从开始刷力扣,也有些许日子了,从一开始的每日一题,到每日两题,再到学习学到无聊的时候就去刷题,也算是经历了一番蜕变。

从一开始的什么都不懂,做题全靠暴力破解,但现在掌握了几个方法。

也了解了一些关于数据结构与算法的小知识

学习新知识固然重要,但是也需要总结之前的知识,毕竟温故而知新嘛

1. 二分法

二分查找法是一种算法

他经常用在:

给定一个升序的数组/列表和一个目标值,尽可能快的查找其中的目标值

若存在,返回目标值得索引

若不存在,返回-1

这样的场景

相比于直接遍历整个数组,使用二分法无疑会让我们的程序效率更高!

因为是升序的,所以我们可以以数组中间的元素为中线,将数组分为左右两个数组

python代码展示:

target = 7  # 给一个目标值
start = 0  # 用于计算中间值,和后面陆续的将数组划分为两个数组
end = len(li)-1 # 用于计算中间值,记录列表最后值的索引
li = [1, 2, 3, 4, 5, 6 ,7, 8, 9, 10]
while start<end:# 记录一个循环mid = (start+n)//2  # 值为4"""一个升序数组/列表以中间mid(//是保持中间值为整数)为界限看似分成两个数组li_left = [1, 2, 3 ,4, 5]li_right = [6, 7, 8, 9, 10]"""if target>li[mid]:# 如果目标值比中间值大,就说名目标值(7)在右边的列表start = mid+1 # 让start变成右边列表的第一个元素的索引# 抛弃左边的列表不要,只看右边的列表li_right = [6, 7, 8, 9, 10]else:# 如果目标值小于等于中间值,就说明目标值在左边的列表end = mid # 让n变成左边列表的最大值的索引# 抛弃右边的列表不要,只看左边的列表
print("mid的值就是目标值的索引:", mid)
# 运行结果为6

Java代码:

public class Test{public static void main(String[] args){int[] aa = new int[]{1, 2, 3, 4, 5, 6 ,7, 8, 9, 10};int target = 7;  // 给一个目标值,查找目标值是否在数组中int start = 0;  // 用于计算中间值,和后面陆续的将数组划分为两个数组int mid = 0;    // 设置中间值遍历int end = aa.length; // 用于计算中间值,记录列表最后值的索引while(start<end){      // 设置循环条件,当头指针小于尾指针时终止循环mid = (start+end)/2;/*一个升序数组/列表以中间mid(//是保持中间值为整数)为界限看似分成两个数组左边是: [1, 2, 3 ,4, 5]右边是: [6, 7, 8, 9, 10]*/if (target>aa[mid]) start = mid+1;  // 如果目标值比中间值大,就说名目标值(7)在右边的列表,让start变成右边列表的第一个元素的索引else end = mid;   // 如果目标值小于等于中间值,就说明目标值在左边的列表,让end编程左边列表的尾部}System.out.println("mid的值就是目标值在数组中的索引:"+mid);}
}// 运行结果为6

随着循环的进行,列表会越来越小,最后只剩目标值,然后最小值的索引就是我们需要的值

二分法时间复杂度分析:O(logn) 每次循环使数组长度减半,因此又被称为折半查找法

直接遍历整个数组(暴力解法)时间复杂度分析:O(n)

2. 双指针法

在我们的二分法中就是用了双指针的方法,起始时一个指针指向数组的头部,一个指针指向数组的尾部,使用这种方法会让我们对数组的操作更加流畅一些。

双指针法常常是用在:

查找某些元素时

力扣的第一道题就是一个经典的双指针优化程序的题目

给你一个目标值和一个有序数组

找出数组中和为目标值的元素

返回她们的下标

元素不能与自己相加

正常的做法是进行嵌套循环,挨个查找,这样的时间复杂度为:O(n*2)

而如果使用双指针的方法,结合二分法就能使时间复杂度降低到:O(logn)

遍历的方法就相当于一个人在找东西,双指针的方法就好像是两个人在找东西

打个例子:

我有一块种着10棵树的地

有人告诉我,你有一棵树需要浇水了

如果只有我自己(正常遍历)

并且我不需要跑到树前面观察才能判断我的树是否需要浇水

我只能一棵一棵的找,然后判断

而如果我有一个助手(双指针)

我就可以缩短排查的时间

java:

public class Shuzu {public static void main(String[] args) {int target = 7;int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};System.out.println(ArrD(7,arr)+"\n"+ArrS(target,arr));}static int ArrD(int target, int[] arr) {// 单指针for (int i = 0; i < arr.length; i++) {if (arr[i] == target) return i;}return -1;}static int ArrS(int target, int[] arr){// 双指针int end = arr.length-1;int start = 0;while (start<end){if (arr[start]==target) return start;if (arr[end]==target) return end;start++;end--;}return -1;}
}

py:

def ArrD(target, arr):# 单指针for i in range(len(arr)):if arr[i]target: return ireturn -1;
def ArrS(target, arr):# 双指针start = 0end = len(arr)-1while start<end:if arr[start]==target: return startif arr[end]==target: return endstart+=1end-=1return endtarget = 7
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(ArrD(target, arr), "\n", ArrS(target, arr))

3. 递归

递归与其说是一种算法,不如说是一种思想。

它更类似于我们高中数学学过的数列的递推推导式:A(n) = A(n-1)+5 首项为1

让你通过这个式子计算第n项的值的话

你高中会使用它推导出一个通项公式,再将n代入求解

但是再计算机眼里就不用这么麻烦

你只需要每次调用这个公式,然后计算出值就好

在编程语言里就是 :定义一个函数,调用自身,返回结果就是递归

就相当于计算机帮你从1开始执行了很多遍的A(n) = A(n-1)+5

无限套娃?不不不,他还是有个限度的,没法无限,哈哈哈

比如需要求A(5),那么就是:

A(5) = A(4)+5

A(4) = A(3)+5

A(3) = A(2)+5

A(2) = A(1)+5

A(1) = 3

A(5) = 3+5+5+5+5=23

代码实现:

java代码:

public class Digui {public static void main(String[] args) {int sum = Shu(5);System.out.println(sum);}static int Shu(int n){if (n<=1) return 3;else return Shu(n-1)+5;}
}

py代码:

def Shu(n:int)->int:if n<=1: return 3else: return Shu(n-1)+5print(Shu(5))

最后的计算结果是23

4. 数组

什么是数组?数组就是存储多个相同数据的集合,他们的内存地址是相邻的,所以可以通过数组取值。

这么说,是不是有点不好理解,那么这样呢?

我有一颗白菜,手拿着就能回家,那如果是十几颗呢?

我就可以用麻袋!麻袋!装进去,带回家!是的你要存的数据就是白菜,而这个数组就是你要用的麻袋~~~~~

麻袋中的白菜怎么拿出来我需要用的呢?

下标,数组中的下标是以0开始的,什么是下标,就是你从0开始查,查到某个你要的数据,查到几,下标就是几,就相当于,我在装白菜的时候,说“这是第0个白菜,这是第1个白菜…”,而他们也能听懂(别管他们能不能听懂,我说能就能,哈哈~~),等我需要哪一颗白菜的时候,喊一声,他就自己跳出来了

当然我们的数组一般存储的数据比较多,而计算机又不和人一样能够直接看到数组的全部元素,他只记得里面第一颗白菜的样子,所以我们在查找某个元素,但是又不知道他在哪里的时候,只能通过遍历的手段来获取了

遍历每一棵白菜,将他与我们需要找的白菜对比没如果是就不找了,如果不是就继续找。

具体的代码形式我就不多说了,这个都是知道的。

5. 字符串

字符串是我们在编程语言里面见到的第一个数据结构 hello world

当然,字符串不仅是我们滴各一人士的数据结构,也是我们在生活中用到最多的,比如我们网上聊天,就是字符串,看的小说,是字符串…

而有的字符擦混存储在文件中供计算机读取,然后输出到屏幕上给我们看。

字符串可以看成是一个字符型数组,但是又不尽相同

字符串可以遍历,查询,拼接,但是不能修改

有的时候拼接用得好也能很大程度上降低我们解决问题的难度

我们可以通过运算符号对字符串进行

运算符 作用 实例
+ 拼接字符串 “a”+“a”=>“aa”
= 赋值字符串 “a”=“b”=>“b”
== 判断字符串是否相等 “a”==“b”=>false
[] 通过下标获取字符串中的字符 “asd”[0]=>“a”

说起字符串,能说的也可以很多,也可以很少

说多了有AI的NLP自然语言处理,K近邻算法,正则表达式…

这里就不多说了,先学会基本操作

6. 链表

链表是一种抽象的数据结构,他实际上是一个链表对象,头结点就是这个链表对象,而链表的没一个节点都是一个对象。

链表是一个不定长的线性表数据结构,链表没有内置方法来获取其长度,只能通过遍历来获得里面的内容。

链表实现:

java:

class ListNode{public int val;     // 存储的值public ListNode next;    // 指向下一节点public ListNode(int val){   // 构造函数/方法this.val = val;next = null;}
}

py:

class ListNode:def __init__(self,val):  # 构造函数self.val = val   # 存储的值next = None      # 指向下一节点

是的,链表就是这样实现的。我们一般只能拿到头结点,然后通过判断下一节点是否为空位约束条件来终止循环。

实例:

给你个链表[1, 2, 3, 4, 5]

求链表的长度

java代码:

package com.example.demo;public class ListNodeStudy {public static void main(String[] args) {ListNode h1 = new ListNode(1);    // 1ListNode h2 = new ListNode(2);    // 2ListNode h3 = new ListNode(3);    // 3ListNode h4 = new ListNode(4);    // 4ListNode h5 = new ListNode(5);    // 5h1.next = h2;    // 下一节点h2.next = h3;    // 下一节点h3.next = h4;    // 下一节点h4.next = h5;    // 下一节点// 题目的链表是这样是实现的,不过不会让你去实现,而是给你h1让你来找长度System.out.println(len(h1));}static int len(ListNode head){int len = 0;   // 为链表长度定义变量while (head!=null){   // 遍历链表获取长度len++;head = head.next;}return len;}
}
class ListNode{public int val;     // 存储的值public ListNode next;    // 指向下一节点public ListNode(int val){   // 构造函数/方法this.val = val;next = null;}
}

py:

class ListNode:def __init__(self, val):  # 构造函数self.val = val  # 存储的值self.next = None  # 指向下一节点h1 = ListNode(1)
h2 = ListNode(2)
h3 = ListNode(3)
h4 = ListNode(4)
h5 = ListNode(5)
h1.next = h2
h2.next = h3
h3.next = h4
h4.next = h5def ListNodeLen(head: ListNode) -> int:len = 0while head != None:len += 1head = head.nextreturn lenprint(ListNodeLen(h1))

三、结语

也许我学的慢,但是我始终都在进步!那我总有一天会成功。

零基础的我刷力扣一周后,总结了点东西相关推荐

  1. 【关于为什么要刷力扣的思考】记第二次周赛AK

    前言 从上次AK周赛的一月底,磕磕绊绊到五月初,总共经历了20多场的周赛 在这20场周赛中,四题:三题:两题:一题 = 2:12:8:1 总体来说应该还是在两到三题中间徘徊 但很多时候做出的两题,并非 ...

  2. VS Code刷力扣LeetCode方法

    VS Code刷力扣LeetCode方法 一.LeetCode扩展安装 二.Node.js安装 三.账号登录 3.1 选择 力扣中国版 3.2 选择 Cookies方式登录 3.3 Cookies获取 ...

  3. 在 vscode 上刷力扣 Leetcode 可以这样来

    背景 神奇的算法网站 LeetCode 值得驻留,网页版似乎不太方便,作为习惯于在编译器上敲代码的你,如何 vscode 上优雅的刷力扣 Leetcode,在本地配置,记录下来方便备查. 环境前置:电 ...

  4. 程序员面试需要刷力扣算法题吗

    这里写目录标题 1. 程序员面试需要刷力扣算法题吗 1.1. 算法题的一些特征 1.2. 为什么要考查算法 1.3. 目前面试主要考查 3 类 1. 程序员面试需要刷力扣算法题吗 1.1. 算法题的一 ...

  5. 零基础html学习/刷题-第一期

    之前写的html学习的文章都是零零散散的,这次出个整合的专栏,把内容集中起来,做个知识复盘,顺带刷刷题.牛客网非常值得一用,刷题也很好刷!对于基础入门最合适不过. 博主主页:WDm-xmax 原id: ...

  6. 20201219:力扣219周周赛题解

    力扣219周周赛题解 题目 思路与算法 代码实现 复杂度分析 题目 比赛中的配对次数 十-二进制数的最少数目 石子游戏 VII 堆叠长方体的最大高度 思路与算法 比赛中的配对次数 两两比赛,淘汰剩一支 ...

  7. 20201007:力扣209周周赛题解记录(上)

    力扣209周周赛题解记录(上) 题目 思路与算法 代码实现 复杂度分析 题目 特殊数组的特征值 奇偶树 思路与算法 第一题单纯的暴力就行,应该是可以用二分之类的改善复杂度,没必要赘述,直接上暴力遍历, ...

  8. 20200616:力扣193周周赛上

    力扣193周周赛上 题目 思路与算法 代码实现 写在最后 题目 一维数组的动态和 不同整数的最少数目 思路与算法 第一题没啥好说的,动态和,dp最基础的东西. 第二题主要是一个贪心的过程,既然要剩下的 ...

  9. 20200505:力扣151周周赛上

    力扣151周周赛上 题目 思路与算法 代码实现 题目 查询无效交易 2.比较字符串最小字母出现频次 思路与算法 第一题直接将我们需要的这四组数据包装成一个Transaction对象,主要是注意书写问题 ...

最新文章

  1. 获取当前脚本目录路径问题汇总
  2. 理解Linux和其他UNIX-Like系统上的平均负载
  3. java 内存_java节省内存的几条建议
  4. Q1全球智能机销量增长3.9% 三星苹果华为居三甲
  5. 全文索引 排名计算问题
  6. 聊聊高并发(三十三)Java内存模型那些事(一)从一致性(Consistency)的角度理解Java内存模型
  7. 常用命令-tar 加密
  8. php mysql 排名算法_MySQL PHP:优化排名查询和计数子查询
  9. php 支付加密,关于支付时rsa加密解密的函数
  10. Juqery Html(),append()等方法的Bug
  11. SQL Server 不同数据库导入指定数据解决方案
  12. 想买基金,在哪个银行开户好呢?
  13. 组织健康的路径:良性互动
  14. layui select change事件_一道2020年全国生物学联赛试题背后的“眼齿鸟事件”
  15. NYOJ 93 汉诺塔(三) 【栈的简单应用】
  16. win10连接共享打印机_win7共享出来的打印机部分电脑无法连接的问题
  17. Kali安装AWVS
  18. python网络测速_网络测速命令--speedtest
  19. PLC、PAC、PC-Based、软PLC傻傻分不清
  20. python从图片提取文字_用python提取图片文字

热门文章

  1. 如何使用在线网站绘制基本的流程图
  2. revit插件加载位置 addin 文件位置
  3. 倾角传感器和IMU的区别是哪些?
  4. 2022第五空间网络安全大赛
  5. SpringBoot + Vue 用户登入token 之租房管理系统后台 模板
  6. CMake学习(五) —— 打印信息
  7. SPAN /SPAN 这个标签有什么用 ,指的是什么?
  8. 1253:抓住那头牛(数轴上的问题)
  9. 最新手机厂商Android kernel内核下载
  10. 天哪,我只是想吃顿红烧肉啊