【Python 算法零基础 2.模拟 ① 基于数组】

思念随风飘荡,落在水中央

                                —— 25.3.19

        模拟算法就是根据题目要求解题,一些复杂的模拟题只是把一些简单操作组合起来🚀

数据结构

        对于模拟题而言,最关键的是数据结构,看到一个问题,选择合适的数据结构,然后根据问题来实现对应的功能。模拟题的常见数据结构是:数组、字符串、矩阵、链表、二叉树等

基于数组

        利用数组的数据结构,根据题目要求实现算法,如:

1920.基于排列构建数组、1389.按既定顺序创建数组、1603.设计停车系统、2149.按符号重拍数组、2221.数组的三角和

Ⅰ、1920. 基于排列构建数组

给你一个 从 0 开始的排列 nums下标也从 0 开始)。请你构建一个 同样长度 的数组 ans ,其中,对于每个 i0 <= i < nums.length),都满足 ans[i] = nums[nums[i]] 。返回构建好的数组 ans 。

从 0 开始的排列 nums 是一个由 0 到 nums.length - 10 和 nums.length - 1 也包含在内)的不同整数组成的数组。

示例 1:

输入:nums = [0,2,1,5,3,4]
输出:[0,1,2,4,5,3]
解释:数组 ans 构建如下:
ans = [nums[nums[0]], nums[nums[1]], nums[nums[2]], nums[nums[3]], nums[nums[4]], nums[nums[5]]]
    = [nums[0], nums[2], nums[1], nums[5], nums[3], nums[4]]
    = [0,1,2,4,5,3]

示例 2:

输入:nums = [5,0,1,2,3,4]
输出:[4,5,0,1,2,3]
解释:数组 ans 构建如下:
ans = [nums[nums[0]], nums[nums[1]], nums[nums[2]], nums[nums[3]], nums[nums[4]], nums[nums[5]]]
    = [nums[5], nums[0], nums[1], nums[2], nums[3], nums[4]]
    = [4,5,0,1,2,3]

提示:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] < nums.length
  • nums 中的元素 互不相同

思路与算法

① 初始化

        变量 n数组 nums长度

        ans 是一个空列表,用于存储最终结果

② 遍历数组

        使用 for 循环遍历数组 nums 的每一个索引 i

        对于每一个索引 i,将 nums[nums[i]] 的值添加到 ans

③ 返回结果

        遍历结束后,返回 ans 

class Solution:
    def buildArray(self, nums: List[int]) -> List[int]:
        n = len(nums)
        ans = []
        for i in range(n):
            ans.append(nums[nums[i]])
        return ans


Ⅱ、1389. 按既定顺序创建目标数组

给你两个整数数组 nums 和 index。你需要按照以下规则创建目标数组:

  • 目标数组 target 最初为空。
  • 按从左到右的顺序依次读取 nums[i] 和 index[i],在 target 数组中的下标 index[i] 处插入值 nums[i] 。
  • 重复上一步,直到在 nums 和 index 中都没有要读取的元素。

请你返回目标数组。

题目保证数字插入位置总是存在。

示例 1:

输入:nums = [0,1,2,3,4], index = [0,1,2,2,1]
输出:[0,4,1,3,2]
解释:
nums       index     target
0            0        [0]
1            1        [0,1]
2            2        [0,1,2]
3            2        [0,1,3,2]
4            1        [0,4,1,3,2]

示例 2:

输入:nums = [1,2,3,4,0], index = [0,1,2,3,0]
输出:[0,1,2,3,4]
解释:
nums       index     target
1            0        [1]
2            1        [1,2]
3            2        [1,2,3]
4            3        [1,2,3,4]
0            0        [0,1,2,3,4]

示例 3:

输入:nums = [1], index = [0]
输出:[1]

提示:

  • 1 <= nums.length, index.length <= 100
  • nums.length == index.length
  • 0 <= nums[i] <= 100
  • 0 <= index[i] <= i

思路与算法

① 初始化

        创建一个空列表 res,用于存储最终结果

② 遍历数组

        使用 for 循环遍历 index 数组的每一个索引 i

        对于每个索引 i,使用 insert 方法将 nums[i] 插入到 res 的 index[i] 的位置

③ 返回结果 

        遍历结束后,返回 res 

class Solution:
    def createTargetArray(self, nums: List[int], index: List[int]) -> List[int]:
        res = []
        for i in range(len(index)):
            res.insert(index[i], nums[i])
        return res


Ⅲ、1603. 设计停车系统

请你给一个停车场设计一个停车系统。停车场总共有三种不同大小的车位:大,中和小,每种尺寸分别有固定数目的车位。

请你实现 ParkingSystem 类:

  • ParkingSystem(int big, int medium, int small) 初始化 ParkingSystem 类,三个参数分别对应每种停车位的数目。
  • bool addCar(int carType) 检查是否有 carType 对应的停车位。 carType 有三种类型:大,中,小,分别用数字 1, 2 和 3 表示。一辆车只能停在  carType 对应尺寸的停车位中。如果没有空车位,请返回 false ,否则将该车停入车位并返回 true 。

示例 1:

输入:
["ParkingSystem", "addCar", "addCar", "addCar", "addCar"]
[[1, 1, 0], [1], [2], [3], [1]]
输出:
[null, true, true, false, false]

解释:
ParkingSystem parkingSystem = new ParkingSystem(1, 1, 0);
parkingSystem.addCar(1); // 返回 true ,因为有 1 个空的大车位
parkingSystem.addCar(2); // 返回 true ,因为有 1 个空的中车位
parkingSystem.addCar(3); // 返回 false ,因为没有空的小车位
parkingSystem.addCar(1); // 返回 false ,因为没有空的大车位,唯一一个大车位已经被占据了

提示:

  • 0 <= big, medium, small <= 1000
  • carType 取值为 1, 2 或 3
  • 最多会调用 addCar 函数 1000 次

思路与算法

① 初始化

输入:big(大型车位数量)、medium(中型车位数量)、small(小型车位数量)

处理:将输入的车位数量赋值给类的属性self.bigself.mediumself.small

输出:

② 添加车辆

输入:carType(车辆类型)

处理:

        判断carType的值,如果carType为 1,检查self.big是否大于等于 1。如果是,则将self.big减 1 并返回True;否则返回False

        如果carType为 2,检查self.medium是否大于等于 1。如果是,则将self.medium减 1 并返回True;否则返回False

        如果carType为其他值,检查self.small是否大于等于 1。如果是,则将self.small减 1 并返回True;否则返回False

输出:True(停车成功)或False(停车失败)

class ParkingSystem:

    def __init__(self, big: int, medium: int, small: int):
        self.big = big
        self.medium = medium
        self.small = small

    def addCar(self, carType: int) -> bool:
        if carType == 1:
            if self.big >= 1:
                self.big -= 1
                return True
        elif carType == 2:
            if self.medium >= 1:
                self.medium -= 1
                return True
        else:
            if self.small >= 1:
                self.small -= 1
                return True
        return False
        


# Your ParkingSystem object will be instantiated and called as such:
# obj = ParkingSystem(big, medium, small)
# param_1 = obj.addCar(carType)


Ⅳ、2149. 按符号重排数组

给你一个下标从 0 开始的整数数组 nums ,数组长度为 偶数 ,由数目 相等 的正整数和负整数组成。

你需要返回满足下述条件的数组 nums

  1. 任意 连续 的两个整数 符号相反
  2. 对于符号相同的所有整数,保留 它们在 nums 中的 顺序 。
  3. 重排后数组以正整数开头。

重排元素满足上述条件后,返回修改后的数组。

示例 1:

输入:nums = [3,1,-2,-5,2,-4]
输出:[3,-2,1,-5,2,-4]
解释:
nums 中的正整数是 [3,1,2] ,负整数是 [-2,-5,-4] 。
重排的唯一可行方案是 [3,-2,1,-5,2,-4],能满足所有条件。
像 [1,-2,2,-5,3,-4]、[3,1,2,-2,-5,-4]、[-2,3,-5,1,-4,2] 这样的其他方案是不正确的,因为不满足一个或者多个条件。 

示例 2:

输入:nums = [-1,1]
输出:[1,-1]
解释:
1 是 nums 中唯一一个正整数,-1 是 nums 中唯一一个负整数。
所以 nums 重排为 [1,-1] 。

提示:

  • 2 <= nums.length <= 2 * 105
  • nums.length 是 偶数
  • 1 <= |nums[i]| <= 105
  • nums 由 相等 数量的正整数和负整数组成

方法一、分别存储正负整数再合并 

思路与算法 
① 初始化

        变量 n 是数组 nums 的长度

        列表 nZ 用于存储所有的正整数

        列表 nF 用于存储所有的负整数

        列表 res 用于存储最终结果

② 遍历链表

        使用 for 循环遍历数组 nums 中的每一个元素

        如果当前元素是正整数 (nums[i] > 0),则将其添加到列表 nZ 中

        如果当前元素是负整数 (nums[i] < 0),则将其添加到列表 nF 中

③ 交替插入正负数

        使用另一个 for 循环遍历 nZ 和 nF 的索引

        将 nZ[i] 和 nF[i] 交替插入到列表 res 中,确保正数在前

④ 返回结果

        返回重新排列后的列表 res

class Solution:
    def rearrangeArray(self, nums: List[int]) -> List[int]:
        n = len(nums)
        nZ = []
        nF = []
        res = []
        for i in range(n):
            if nums[i] > 0:
                nZ.append(nums[i])
            else:
                nF.append(nums[i])
        for i in range(len(nZ)):
            res.append(nZ[i])
            res.append(nF[i])
        return res

方法二、 按照奇偶索引直接迭代

思路与算法
① 初始化操作

计算输入列表 nums 的长度 n,并创建一个长度为 n 的结果列表 res,初始值全为 0。初始化两个指针 i 和 j,分别用于记录结果列表中放置正数和负数的索引位置。i 初始值为 0,表示结果列表的偶数索引位置;j 初始值为 1,表示结果列表的奇数索引位置。

② 遍历输入列表

使用 for 循环遍历输入列表 nums,循环变量为 k。对于每个元素 nums[k],检查其正负性:如果 nums[k] > 0,将其放置在结果列表 res 的偶数索引位置 i 上,并将 i 增加 2(即指向下一个偶数索引位置)。如果 nums[k] 不大于 0(即负数),将其放置在结果列表 res 的奇数索引位置 j 上,并将 j 增加 2(即指向下一个奇数索引位置)

③ 返回结果

遍历完输入列表后,返回重新排列后的结果列表 res

class Solution:
    def rearrangeArray(self, nums: List[int]) -> List[int]:
        n = len(nums)
        res = [0] * n
        i = 0
        j = 1
        for k in range(n):
            if nums[k] > 0:
                res[i] = nums[k]
                i += 2
            else:
                res[j] = nums[k]
                j += 2            
        return res


Ⅴ、2221. 数组的三角和

给你一个下标从 0 开始的整数数组 nums ,其中 nums[i] 是 0 到 9 之间(两者都包含)的一个数字。

nums 的 三角和 是执行以下操作以后最后剩下元素的值:

  1. nums 初始包含 n 个元素。如果 n == 1 ,终止 操作。否则,创建 一个新的下标从 0 开始的长度为 n - 1 的整数数组 newNums 。
  2. 对于满足 0 <= i < n - 1 的下标 i ,newNums[i] 赋值 为 (nums[i] + nums[i+1]) % 10 ,% 表示取余运算。
  3. 将 newNums 替换 数组 nums 。
  4. 从步骤 1 开始 重复 整个过程。

请你返回 nums 的三角和。

示例 1:

输入:nums = [1,2,3,4,5]
输出:8
解释:
上图展示了得到数组三角和的过程。

示例 2:

输入:nums = [5]
输出:5
解释:
由于 nums 中只有一个元素,数组的三角和为这个元素自己。

提示:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 9

思路与算法

① 获取列表长度并进行边界检查

使用 n = len(nums) 获取输入列表 nums 的长度。检查 n 是否等于 1,如果是,则直接返回列表中的唯一元素,因为长度为 1 的列表的 “三角形和” 就是该元素本身。

② 循环计算新的列表

使用 while 循环,当 n > 1 时执行循环体。创建一个新的列表 newNums,用于存储相邻元素相加并对 10 取余后的结果。使用 for 循环遍历原列表 nums,对于每个位置 i,计算 nums[i] + nums[i + 1] 并对 10 取余,将结果添加到 newNums 中。将 n 减 1,因为每次计算新列表时,列表长度会减少 1。将 nums 更新为 newNums,以便在下一轮循环中继续计算。

③ 返回最终结果

当 n 等于 1 时,循环结束,此时 nums 中只剩下一个元素,返回该元素作为 “三角形和”。

class Solution:
    def triangularSum(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 1:
            return nums[0]
        while n > 1:
            newNums = []
            for i in range(n-1):
                newNums.append((nums[i] + nums[i + 1]) % 10) 
            n -= 1
            nums = newNums
        return nums[0]

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值