目录
1 数据结构与算法简介、LeetCode 入门及攻略
01、数据结构与算法
(1)数据结构
指的是数据的组织结构,用来组织、存储数据。
数据结构可分为逻辑结构和物理结构。
研究数据集结构就是研究两种结构之间的关系,设计算法以提高计算机硬件的利用率。
逻辑结构 - 根据数据元素之间的不同关系可分为一下四种:
1、集合结构:数据元素在一个集合中
特点:数据元素唯一无序
2、线性结构:数据元素一一对应
特点:数据元素左右相邻(除两端元素)
3、树形结构:数据元素呈一堆多关系
特点:多层嵌套,有层次性
4、图形结构:数据元素呈多对多关系
特点:结点之间邻接关系可有可无
物理结构:指数据结构在计算机中的存储方式,常采用两种结构
1、顺序存储结构:数据元素在一片存储单元里
优点:简单、易理解,占用存储空间最少。
缺点:时间效率较低。
2、链式存储结构:数据元素存放在任意的存储单元里,存储单元之间可连续也可不连续
链式存储结构中,每个数据元素占用的存储单元为一个链结点。每个链结还要存放称为指针的地址。指针用来反映数据之间的关系。
优点:不会造成空间浪费;时间效率高。
缺点:占用空间大。
(2)算法
算法代表着用系统的方法解决问题的策略机制。
算法指是解决问题的方法。
算法是一系列运算步骤,用来解决某一类计算问题,最终产生一个输出。
对于一个问题,往往有着不同的算法。
算法的基本特性:输入、输出、有穷性、确定性、可行性
1、输入:在算法开始之前赋给算法的参数。一个算法可以有多个输入,也可以没有输入。
2、输出:算法返回的结果。有一个或多个参数作为算法的输出。
3、有穷性:算法在有限的步骤内结束,时间也应有穷。
4、确定性:组成算法的每一条指令含义清晰明确,无歧义。
5、可行性:算法的每一步操作具有可执行性,可以转换为程序在计算机上运行并得到正确的结果。
算法追求的目标:正确性、可读性、健壮性、时间复杂度更低、空间复杂度更低
研究算法是为了更高效解决问题。算法应该追求以下几个目标:
所需运行时间更少(即时间复杂度低)
占用内存空间更小(即空间复杂度低)
正确性:算法程序运行正常,无语法错误。
可读性:算法简洁易懂,方便阅读,也便于修改和调试。
健壮性:能较好地处理不正常数据
02、算法复杂度
(1)算法复杂度简介
指在一定规模的问题下,程序的时间和空间使用情况。
算法,讲究的是追求运行用更短的时间,占用更少空间、算法复杂度就是从时间和空间层面分析算法的复杂程度的。
比较算法优劣的两种方法:
1、事后统计:用两种不同算法各编写一个程序,并运行,比较两者复杂度,选出优者。
2、预先估算:设计算法,根据算法步骤估算出算法的运行时间和占用空间。比较两个算法,挑出较好的算法。通常采用此方法。
在不考虑计算机条件等外在因素的条件下、我们只关心随着问题规模 扩大时,时间开销、空间开销的增长情况。
(2)时间复杂度
时间复杂度简介
在一定规模(n)的条件下、算法运行所花费的时间,记为T(n)。
度量标准:基本操作次数
基本操作:算法执行中的每条语句
如:
sum=0
for i in range(10):
sum+=i
print(sum)
则时间复杂度为:1+10+1=12
时间复杂度函数表示为 T(n)=O(f(n))
其中,O是渐进符号,用来表示时间复杂度
T(n)表示时间复杂度
渐进符号
用来刻画函数增长速度。常用渐进符号:
Θ 渐进紧确界符号 :
函数 f(n)=Θ(g(n)) 存在两个正数c1,c2。使c1*g(n)<=f(n)<=c2*g(n)
O 渐进上界符号 :
函数f(n)=O(g(n))。存在常量 c,使 0<=f(n)<=c*g(n)。
Ω 渐进下界符号 :
函数 f(n)=Ω(g(n))。存在常量c,使 c*g(n)<=f(n)
时间复杂度计算
步骤:找出基本语句(算法执行最多语句)、计算基本语句数量级、表示时间复杂度
注意原则:加法原则、乘法原则
类型:
1、常数型:代码执行时间不随代码规模增长而增长,记为 O(1)。
a = 1
b = 2
c = a + b
print(c)
2、线性型:只含有一层循环,记为 O(n)。
sum = 0
for i in range(10):
sum+=i
print(sum)
3、平方型:双层嵌套,且两层规模相同,代码执行n*n次,记为O(n2)。
sum = 0
for i in range(10):
for j in range(10):
sum+=1
print(sum)
4、阶乘:常用在递归算法中,时间复杂度为 O(n!)。
def add (n):
if n==0:
return1
for i in range(n):
print(i)
return add(n-1)
5、对数:常出现在二分算法中,时间复杂度为 O(logn)。
sum = 1
while sum<10:
sum*=2
print(sum)
6、线性对数 :常出现排序算法中,记为O(n×logn)
t = 1
r = 0
n = 10
while t < n:
t *= 2
for i in range(n):
r += 1
print(r)
几者之间的大小关系:
O(1) < O(logn) < O(n) < O(n×logn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)。
最佳、最坏、平均时间复杂度
随着问题内容不同出现 [最佳]、[最坏]、[平均]三种情况
最佳时间复杂度:用时最短复杂度。
最坏时间复杂度:用时最长复杂度。
平均时间复杂度:平均用时复杂度。
(3)空间复杂度
空间复杂度简介
一定规模下,算法所占用的空间大小,可以记作为 S(n)。函数表示为 S(n)=O(f(n))
算法的辅助空间作为衡量空间复杂度的标准
主要包括变量占用的存储空间和使用的堆栈空间两个部分。
空间复杂度计算
常数:
a = 1 b = 2 r = a+b print(r)
只使用了局部遍量,空间复杂度在常数范围内,复杂度记为 O(1)。
线性:
def re(n): if n <= 0: return 1 return n * re(n - 1)
递归算法中,每次调用都占用一份空间,复杂度为 O(n)。
空间复杂度大小关系:
O(1) < O(logn) < O(n) < O(n2) < O(2n)
03、LeetCode入门及攻略
(1)LeetCode是什么
LeetCode是一个提供算法题目练习平台。使用LeetCode来练习编程技能,以及提高算法能力。
(2)LeetCode新手入门
注册:
1、打开官网:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台https://leetcode.cn/
2、点击右上角注册或登录:
3、输入手机号验证码登录:
题库:
从顶部点击题库进行练习
根据自己的需求进行分类刷题、也可进行随机刷题
刷题语言:
LeetCode 支持多种编程语言(C、C++、Java、Python 等),
使用 Python 刷题能更加专注于算法与数据结构本身,也能获得更快的刷题效率。
刷题流程:
左侧区域为题目描述,右侧是代码编辑区域。
提交所写的代码后返回结果,判定通过。
04、练习题目
(1)两整数相加
题目:给定两个整数 num1 和 num2,(−100≤num1,num2≤100)要求返回这两个整数的和。
class Solution(object):
def sum(self, num1, num2):
"""
:type num1: int
:type num2: int
:rtype: int
"""
return num1 + num2
思路:使用return 来返回两个整数的和
(2)数组串联
题目:给定一个长度为 n
的整数数组 nums 。构建一个长度为 2n
的答案数组 ans
,数组下标 从 0 开始计数 ,对于所有 0 <= i < n
的 i
,满足下述所有要求:
ans[i] == nums[i]
ans[i + n] == nums[i]
具体而言,ans
由两个 nums
数组 串联 形成,返回数组 ans
。
class Solution(object):
def getConcatenation(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
i = len(nums)
for index in range(i):
nums.append(nums[index])
return nums
思路:本体考察列表的增添
(3)宝石与石头
题目:给定一个字符串 jewels
代表石头中宝石的类型,另有一个字符串 stones
代表你拥有的石头。 stones
中每个字符代表了一种你拥有的石头的类型。计算出拥有的石头中有多少是宝石。
字母区分大小写,因此 "a"
和 "A"
是不同类型的石头。
class Solution(object):
def numJewelsInStones(self, jewels, stones):
"""
:type jewels: str
:type stones: str
:rtype: int
"""
num = 0
for j in jewels:
for s in stones:
if s==j:
num+=1
return num
思路:使用for循环遍历字符串并比较
(4)一维数组的动态和
题目:
给你一个数组 nums
。请返回 nums
的动态和。
数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i])
。
class Solution(object):
def runningSum(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
for i in range(1,len(nums)):
nums[i]+=nums[i-1]
return nums
(5)转换成小写字母
题目:给你一个字符串 s
,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。
class Solution(object):
def toLowerCase(self, s):
"""
:type s: str
:rtype: str
"""
r = ''
for i in s:
if i>="A"and i<="Z":
i=chr(ord(i)+32)
r+=i
return r
思路:大写字母ASCII码值比小写小32,利用函数ord()和chr()实现大小写转换
(6)最富有客户的资产总量
题目:
给你一个 m x n
的整数网格 accounts
,其中 accounts[i][j]
是第 i
位客户在第 j
家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。
客户的资产总量就是他们在各家银行托管的资产数量之和,最富有客户就是资产总量最大的客户。
class Solution(object):
def maximumWealth(self, accounts):
"""
:type accounts: List[List[int]]
:rtype: int
"""
account = 0
for i in accounts:
a = 0
for j in i:
a+=j
if a>account:
account = a
return account