思念随风飘荡,落在水中央
—— 25.3.19
模拟算法就是根据题目要求解题,一些复杂的模拟题只是把一些简单操作组合起来🚀
数据结构
对于模拟题而言,最关键的是数据结构,看到一个问题,选择合适的数据结构,然后根据问题来实现对应的功能。模拟题的常见数据结构是:数组、字符串、矩阵、链表、二叉树等
基于数组
利用数组的数据结构,根据题目要求实现算法,如:
1920.基于排列构建数组、1389.按既定顺序创建数组、1603.设计停车系统、2149.按符号重拍数组、2221.数组的三角和
Ⅰ、1920. 基于排列构建数组
给你一个 从 0 开始的排列
nums
(下标也从 0 开始)。请你构建一个 同样长度 的数组ans
,其中,对于每个i
(0 <= i < nums.length
),都满足ans[i] = nums[nums[i]]
。返回构建好的数组ans
。从 0 开始的排列
nums
是一个由0
到nums.length - 1
(0
和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.big
、self.medium
和self.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
:
- 任意 连续 的两个整数 符号相反
- 对于符号相同的所有整数,保留 它们在
nums
中的 顺序 。- 重排后数组以正整数开头。
重排元素满足上述条件后,返回修改后的数组。
示例 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
的 三角和 是执行以下操作以后最后剩下元素的值:
nums
初始包含n
个元素。如果n == 1
,终止 操作。否则,创建 一个新的下标从 0 开始的长度为n - 1
的整数数组newNums
。- 对于满足
0 <= i < n - 1
的下标i
,newNums[i]
赋值 为(nums[i] + nums[i+1]) % 10
,%
表示取余运算。- 将
newNums
替换 数组nums
。- 从步骤 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]