【Hello Python World】Week 8:Topic 'Array' on LeetCode.com

本周两节课各分析一道题,因为分析的重点不是算法,而是加深语言的用法和认识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]);
}

分析

这个题从算法上看难度不大,关键是要熟悉我们的语言工具。在CC++里要测试一个元素是否存在于一个STL的列表里面,通常需要显式写一个遍历的循环来判断,或者使用find()函数和迭代器来辅助判断,写起来代码最少也需要多些两行,形式并不优美。Python的开发者在语言的简洁性上做了非常多的改进,将一些常用的操作封装成接口,这样程序员写起代码来就简洁不少了。CC++里一个判断元素是否在列表中的两句代码在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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值