2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)

序言

        大一军训结束后的第一天,我开始接受ai studio的招新考核,而考核内容是一次Datawhale的组队学习。凭借不到一个月的Python基础,我将接触Leetcode这个代码在线评测平台,不断刷题以练习编程技能并提高算法能力。这一系列的学习笔记将会在学习期间随着我不断深入的认知而持续修正和更新。

练习题

两整数相加

        给定两个在-100~100区间内的整数 num1 和 num2,返回这两个整数的和。

class Solution(object):
    def sum(self, num1, num2):
        num = num1 + num2
        return num

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第1张图片

       时间复杂度与空间复杂度都是O(1)。

数组串联

        给定一个长度为 n 的整数数组 nums,构建一个长度为 2 * n 的答案数组 ans,答案数组下标从 0 开始计数 ,对于所有 0 <= i < n 的 i ,满足下述所有要求:

  • ans[i] == nums[i]
  • ans[i + n] == nums[i]
class Solution(object):
    def getConcatenation(self, nums):
        nums.extend(nums)
        return nums

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第2张图片 

        这里还有一种更简洁但更耗时的写法。

class Solution(object):
    def getConcatenation(self, nums):
        return nums+nums

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第3张图片

 

宝石与石头

        给定一个字符串 jewels 代表石头中宝石的类型,再给定一个字符串 stones 代表你拥有的石头。stones 中每个字符代表了一种你拥有的石头的类型,计算出拥有的石头中有多少是宝石。

        jewels 和 stones 仅由英文字母组成,jewels 中的所有字符都是唯一的,字母区分大小写,因此 a 和 A 是不同类型的石头。

class Solution(object):
    def numJewelsInStones(self, jewels, stones):
        n = 0
        for i in jewels:
            for j in stones:
                if i == j:
                    n += 1
        return n

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第4张图片 

        这里我使用了双层嵌套循环结构,标答的写法更简洁,采用了sum()函数统计,但牺牲了效率。

class Solution:
    def numJewelsInStones(self, jewels: str, stones: str) -> int:
    # 上面注释了参数可赋的数据类型以及返回值的数据类型
        return sum(s in jewels for s in stones)

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第5张图片

        两种写法的思路一致,时间复杂度O(len(jewels) * len(stones)),空间复杂度O(1),可见该算法运行时间长但占用内存少。若采用哈希集合可牺牲空间复杂度换取时间复杂度,但是实现较为复杂,这里略去。

一维数组的动态和

        给定一个数组 nums,返回数组 nums 的动态和(数组前 i 项元素和构成的数组,计算公式为 runningSum[i] = sum(nums[0] … nums[i])

class Solution(object):
    def runningSum(self, nums):
        lst = []
        for n in range(len(nums)-1,-1,-1):
            j = sum( nums[i] for i in range(len(nums)-n))
            lst.append(j)
        return lst

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第6张图片

        我的思路比较暴力,动态和的每一个元素都从头加算,代价是双层嵌套循环。但是标答的思路采用了递归思想,并采用索引有序修改原数组的各个元素,简洁优雅,有效节省了用时。   

class Solution:
    def runningSum(self, nums: List[int]) -> List[int]:
        for i in range(1, len(nums)):
            nums[i] += nums[i - 1]
        return nums

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第7张图片

       两种方法的空间复杂度均为O(1),但时间复杂度分别是O(len(nums)**2)和O(len(nums))。

转换成小写字母

        给定一个字符串 s,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。

class Solution(object):
    def toLowerCase(self, s):
        return s.lower()

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第8张图片

        时间复杂度O(len(s)),空间复杂度O(1)。

最富有客户的资产总量

        给定一个 m x n 的整数网格 accounts,其中 accounts[i][j] 是第 i 位客户在第 j 家银行托管的资产数量,返回最富有客户所拥有的资产总量(在各家银行托管的资产数量之和)。

class Solution(object):
    def maximumWealth(self, accounts):
        i = 0
        s = sum(accounts[i])
        # sum()函数可直接对数组求和
        while i < len(accounts)-1:
            if s <= sum(accounts[i+1]):
                s = sum(accounts[i+1])
            i += 1
        return s

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第9张图片

        第一次遇到二维数组问题,但巧用前面的递归思想,很好解。但标答直接用max函数秒杀了。时间复杂度O(len(m) * len(n))一样,虽然我的解法的用时会小一点。

class Solution:
    def maximumWealth(self, accounts):
        return max(map(sum, accounts))

2023.9Datawhale_Leetcode_算法入门与数组_学习笔记(一)_第10张图片

数据结构与算法

程序:算法和数据结构的具体实现

数据结构:数据的计算机表示和相应的一组操作。即数据的组织结构,用来组织、存储数据,以提高计算机硬件的利用率。

        逻辑结构:数据元素之间的相互关系

  1. 集合结构:元素无序且唯一 
  2. 线性结构:元素之间「一对一」的线性结构,(除了第一个和最后一个元素)左侧和右侧分别只有一个数据与其相邻【数组、链表、栈、队列、哈希表】
  3. 树形结构:元素之间「一对多」的层次结构【二叉树、多叉树、字典树
  4. 图形结构:元素之间「多对多」的更复杂的非线性结构,由「结点」 和 「边」组成 ,结点之间可任意邻接【无向图、有向图、连通图】​​

        物理结构:数据的逻辑结构在计算机中的存储方式。

  1. 顺序存储结构:将数据元素存放在一片地址连续的存储单元里,数据元素之间的逻辑关系通过数据元素的存储地址来直接反映。
  2. 链式存储结构:将数据元素存放在任意的存储单元里,存储单元可以连续,也可以不连续,数据元素之间的逻辑关系通过指针来间接反映。每个数据元素占用的若干单元的组合称为一个链结点,用于存放一个数据元素的数据信息和指出这个数据元素在逻辑关系的直接后继元素所在链结点的地址(指针)

        前者简单易理解,占用内存少,但需要事先分配一片地址连续的存储单元,对一些操作的时间效率较低;后者时间效率高,可临时申请存储空间,不会造成空间浪费,但指针也要占用存储空间,空间开销大。

算法:解决特定问题求解步骤的准确而完整的描述,在计算机中表现为一系列指令的集合,代表着用系统的方法描述解决问题的策略机制。即解决问题的方法或者过程。

        它可以用 自然语言、编程语言(Python、C、C++、Java 等)描述,也可以用 伪代码、流程图 来表示。

        基本特性

  1. 输入:在算法开始之前最初赋给算法的参数。一个算法可以有多个输入,也可以没有输入(固定不变的问题的解法)
  2. 输出:算法返回的一个或多个结果
  3. 有穷性:算法必须在有限的步骤内结束,并在一个可接受的时间内完成
  4. 确定性:算法的每一个步骤都必须准确定义而无歧义
  5. 可行性:算法的每一步都能通过执行有限次数完成,并且可以转换为程序在计算机上运行并得到正确的结果

        目标

  1. 时间复杂度更低所需运行时间更少
  2. 空间复杂度更低占用内存空间更小
  3. 正确性:算法能满足具体问题的需求,程序运行正常,能通过典型的软件测试
  4. 可读性:算法遵循标识符命名规则,简洁易懂,注释语句恰当,方便自己和他人阅读,便于后期修改和调试
  5. 健壮性:算法对非法数据以及操作有较好的反应和处理

你可能感兴趣的:(算法,leetcode,学习,python,pycharm,数据结构)