LeetCode算法笔记 【第一章:算法入门与数组篇】

目录

1 数据结构与算法简介、LeetCode 入门及攻略

01、数据结构与算法

  (1)数据结构

(2)算法

 02、算法复杂度

(1)算法复杂度简介

(2)时间复杂度

(3)空间复杂度

03、LeetCode入门及攻略

(1)LeetCode是什么

(2)LeetCode新手入门

(3)LeetCode刷题攻略

04、练习题目

(1)两整数相加

(2)数组串联

(3)宝石与石头

(4)一维数组的动态和

(5)转换成小写字母

(6)最富有客户的资产总量



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(log⁡n)。

sum = 1

while sum<10:
    sum*=2
print(sum)

6、线性对数 :常出现排序算法中,记为O(n×log⁡n)

t = 1
r = 0
n = 10
while t < n:
    t *= 2
    for i in range(n):
        r += 1
print(r)

几者之间的大小关系:

O(1) < O(log⁡n) < O(n) < O(n×log⁡n) < 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(log⁡n) < O(n) < O(n2) < O(2n) 


03、LeetCode入门及攻略

(1)LeetCode是什么

LeetCode是一个提供算法题目练习平台。使用LeetCode来练习编程技能,以及提高算法能力。

(2)LeetCode新手入门

注册:

1、打开官网:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台icon-default.png?t=N7T8https://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
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值