本周两节课各分析一道题,因为分析的重点不是算法,而是加深语言的用法和认识Python和之前学习的语言的差异,所以我选的两道题都不是非常复杂。
27.移除元素
题目
给定一个数组 nums
和一个值 val
,你需要原地移除所有数值等于 val
的元素,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(1)
额外空间的条件下完成。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定
nums = [3,2,2,3]
,val = 3
,函数应该返回新的长度
2
, 并且nums
中的前两个元素均为2
。你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定
nums = [0,1,2,2,3,0,4,2]
,val = 2
,函数应该返回新的长度
5
, 并且nums
中的前五个元素为0, 1, 3, 0, 4
。注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
分析
这个题从算法上看难度不大,关键是要熟悉我们的语言工具。在C
或C++
里要测试一个元素是否存在于一个STL的列表里面,通常需要显式写一个遍历的循环来判断,或者使用find()
函数和迭代器来辅助判断,写起来代码最少也需要多些两行,形式并不优美。Python的开发者在语言的简洁性上做了非常多的改进,将一些常用的操作封装成接口,这样程序员写起代码来就简洁不少了。C
或C++
里一个判断元素是否在列表中的两句代码在Python里就是一个简单的关键字in
,使用xxx in list
这样的条件描述,这道题可以秒杀。
还有一个需要重温的点,就是老师上课讲过的:
Python中函数的参数原理上都是按引用传递的,但是在函数里修改普通的各种类型变量,不会对实参产生任何副作用,但是传列表时,函数内也可以对原列表直接改动
综合以上,不算上题目给的代码,真正手写的就三行而已,非常简洁。
代码
class Solution(object):
def removeElement(self, nums, val):
while val in nums:
nums.remove(val)
return len(nums)
54. 螺旋矩阵
题目
给定一个包含m x n
个元素的矩阵(m
行, n
列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
分析
这一道题和老师上课讲的那个旋转图像的题看起来相似,实则算法不同,不过也不难。
在这道题里面展示了Python的两个语法:
- 可以同时多对赋值,比如
x, y = 1, 2
,Python支持这样的写法,等价于x = 1, y = 2
- 下标遍历的从大到小和从小到大的两种做法,其中从大到小需要使用
reversed()
方法
代码也是比较简洁,结束的条件是当上下左右边界相等的时候,就不再走。
代码
class Solution:
def spiralOrder(self, matrix):
#若result是空表,那就返回一个空表就好了,否则下面的读[0][0]号元素会翻车
result = []
if not matrix:
return result
left, right, top, bottom = 0, len(matrix[0]) - 1, 0, len(matrix) - 1
while left <= right and top <= bottom:
for j in range(left, right + 1):
result.append(matrix[top][j])
for i in range(top + 1, bottom):
result.append(matrix[i][right])
for j in reversed(range(left, right + 1)):
if top < bottom:
result.append(matrix[bottom][j])
for i in reversed(range(top + 1, bottom)):
if left < right:
result.append(matrix[i][left])
left, right, top, bottom = left + 1, right - 1, top + 1, bottom - 1
return result