LeetCode刷题1:第一周
相关系列笔记:
LeetCode刷题:前言
LeetCode刷题1:第一周
LeetCode刷题1:第二周
LeetCode刷题1:第三周
LeetCode刷题1:第四周
LeetCode刷题1:第五周
LeetCode刷题1:第六周
LeetCode刷题1:第七周
前言
本周Topic是【数组】,对应的5道题:
26.删除排序数组中的重复项
88.合并两个有效数组
287.寻找重复数
11.盛水最多的容器
4.寻找两个正序数组的中位数
知识点
1、数组:数组用于在单个变量中存储多个值。数组是一种特殊变量,能够一次包含多个值。
2、数组函数:
- len()函数:计算列表元素个数
- list(seq)函数:将元组转换为列表
- max()函数:返回列表元素的最大值
- min()函数:返回列表元素的最小值
3、数组方法:
Python 提供一组可以在列表或数组上使用的内置方法。
方法 | 描述 |
---|---|
append() | 在列表的末尾添加一个元素 |
clear() | 删除列表中的所有元素 |
copy() | 返回列表的副本 |
count() | 返回具有指定值的元素数量。 |
extend() | 将列表元素(或任何可迭代的元素)添加到当前列表的末尾 |
index() | 返回具有指定值的第一个元素的索引 |
insert() | 在指定位置添加元素 |
pop() | 删除指定位置的元素 |
remove() | 删除具有指定值的项目 |
reverse() | 颠倒列表的顺序 |
sort() | 对列表进行排序 |
4、具体实现:
(1)Python多维数组
通过索引号来引用数组元素。数组索引从0开始。
python中的二维数组可以声明如下。
arr2d = [[1,3,5], [2,4,6]]
print(arr2d[0])
它将产生以下输出:
[1, 3, 5]
类似地,我们可以在python中定义三维数组或多维数组。
现在我们知道如何在python中定义和初始化一个数组。我们将研究我们可以在python数组上执行的不同操作。
(2)Python数组遍历使用for循环
可以使用for循环遍历数组的元素。
可以使用 for in 循环遍历数组的所有元素。
下面是一个简单的例子,for循环遍历一个数组。
number_list = ["一", 2, 3, 4, 5, 6]
# 语法结构:for 变量名称(随便定义一个变量) in 列表名称:
# 每一次循环都会把数据保存在新建的变量nub中
for nub in number_list:
print(nub)
(3)使用for循环遍历2D数组
以下代码按行显示元素,然后下一个部分打印给定数组的每个元素。
// 二维数组
var arr = [
[1,2,3,4],
[2,4,6,8],
[6,4,9,0]
];
// 循环遍历二维数组
for(var i = 0;i<arr.length;i++){//循环最外面的数组
for(var j = 0;j<arr[i].length;j++){//循环里面的数组
alert(arr[i][j]);//弹出数组中的每一项
}
}
(4)Python数组追加
可以使用 append() 方法把元素添加到数组中。
(5)Python数组长度
使用 len() 方法来返回数组的长度(数组中的元素数量)。
注:数组长度总是比最高的数组索引大一个。
(6)Python数组切片
Python提供了使用切片符号从另一个数组创建数组的特殊方法。我们来看一些python数组切片的例子。
ARR = [ 1,2,3,4,5,6,7 ]
下图显示了python数组切片示例程序输出。
(7)Python数组插入
可以使用 insert() 函数在数组中插入一个元素。
(8)Python数组弹出
可以调用数组中的pop函数,从指定索引的数组中删除一个元素。
也可以使用 remove() 方法从数组中删除元素。
注:列表的 remove() 方法仅删除首次出现的指定值。
LeetCode例题
26. 删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums= [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
实现:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
"""
(1)双指针,慢指针i从0开始,快指针j从1开始,两个指针每次移动一步。
(2)当i与j所指的数字不同时,i后移一步,把j的值复制给i,j后移一步;
(3)当i与j所指的数字相同时,i不动,j后移一步;
(4)重复步骤2,3直到j指针走完整个数组。
(5)至此,数组的前(i+1)个元素包含了原数组的所有元素,且不重复。所以,返回值为(i+1)
"""
if not nums:
return 0
i=0
j=1
while j<len(nums):
if nums[i] == nums[j]:
j += 1
else:
nums[i+1] = nums[j]
i += 1
return i+1
88. 合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
说明:
- 初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
- 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入: nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n= 3
输出:[1,2,2,3,5,6]
实现:
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
# nums1中,从m开始到结束的长度即为nums2的长度,这部分的‘0’可以看成是nums2的占位符
# 切片,再排序
nums1[:]=sorted(nums1[:m]+nums2[:n])
287. 寻找重复数
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
示例 1:
输入: [1,3,4,2,2]
输出: 2
示例 2:
输入: [3,1,3,4,2]
输出: 3
说明:
- 不能更改原数组(假设数组是只读的)。
- 只能使用额外的 O(1) 的空间。
- 时间复杂度小于 O(n2) 。
- 数组中只有一个重复的数字,但它可能不止重复出现一次。
实现:
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
# 排序后,选择重复的数字
nums.sort()
for i in range(0, len(nums)):
if nums[i] == nums[i+1]:
return nums[i]
11. 盛最多水的容器
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
示例 1:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入:height = [1,1]
输出:1
示例 3:
输入:height = [4,3,2,1,4]
输出:16
示例 4:
输入:height = [1,2,1]
输出:2
实现:
class Solution:
def maxArea(self, height: List[int]) -> int:
"""
思路:双指针法,两个指针分别指向数组的头和尾,计算此刻两个指针所指的元素构成的容器容积,
然后每次移动指向数字小的那个指针。
"""
if not height: return 0
l, r, res = 0, len(height)-1, 0
while l < r:
w = r - l # 计算容器的底部长度
h = min(height[l], height[r]) # 容器的高由最小的值决定(木桶原理,装多少水往往由最短的木板决定)
area = w * h # 计算面积
res = max(res, area) # 寻找最大的面积
if height[l] <= height[r]: # 每次移动指向数字小的那个指针
l += 1
else:
r -= 1
return res
4. 寻找两个正序数组的中位数
给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。
进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
示例 3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例 4:
输入:nums1 = [], nums2 = [1]
输出:1.00000
示例 5:
输入:nums1 = [2], nums2 = []
输出:2.00000
实现:
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
nums = nums1+nums2
nums.sort()
n = len(nums)
if n % 2 == 0:
return float((nums[int(n/2)]+nums[int((n/2)-1)])/2)
else:
return float(nums[int((n-1)/2)])