程序设计中,有一种最最基础的数据结构是数组,数组把相同类型的若干个元素按连续顺序存储在内存中。数组通过索引来记录元素的位置。大多数编程语言中,数组的索引从0开始。如果索引超出了数组的范围,会报数组越界异常。
在Python中,数组中的元素类型不要求必须保持一致,而且支持负数索引,比如-1表示数组中最后一个元素。在Python中,数组被封装成列表(List),是一种容器类型,具有更多的高级功能。例如:
- 列表将数组插入、删除数据时搬移其他数据的操作进行了封装。
- 列表支持动态扩容。
在项目开发中,对于业务开发,大部分情况下,直接使用容器类型就足够了,省时省力。只有在追求极致性能、非常底层的应用开发时,才使用数组。这一小节,我从Leetcode上挑选了几个题目,一起学习一下在Python列表上,如何解决常见的算法问题。
1. 有序数组的平方
题目来源https://leetcode-cn.com/problems/squares-of-a-sorted-array/
给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
示例 1:
输入:[-4,-1,0,3,10]
输出:[0,1,9,16,100]
示例 2:
输入:[-7,-3,2,3,11]
输出:[4,9,9,49,121]
【解题思路1】
利用python中的列表生成式生成平方后的数组,再利用排序函数sorted()对求平方后的数组进行排序。
【代码实现1】
class Solution:
def sortedSquares(self, A: List[int]) -> List[int]:
return sorted([x*x for x in A])
【解题思路2】
利用python中的map函数对数组A的每个元素求平方,需要借助lambda匿名函数表示求平方。再利用排序函数sorted()对求平方后的数组进行排序。
【代码实现2】
class Solution:
def sortedSquares(self, A: List[int]) -> List[int]:
return sorted(map(lambda x: x**2, A))
2. 三个数组成的最大乘积
题目来源: https://leetcode-cn.com/problems/maximum-product-of-three-numbers/
示例 1:
输入: [1,2,3]
输出: 6
示例 2:
输入: [1,2,3,4]
输出: 24
【解题思路】
乘积最大值有两种情况,3个最大正数,或2最小负数和1个正数。
【代码实现】
class Solution:
def maximumProduct(self, nums: List[int]) -> int:
l = sorted(nums, reverse=True)
return max(l[0]*l[1]*l[2], l[-1]*l[-2]*l[0])
3. 存在连续三个奇数的数组
题目来源https://leetcode-cn.com/problems/three-consecutive-odds/
给你一个整数数组 arr,请你判断数组中是否存在连续三个元素都是奇数的情况:如果存在,请返回 true ;否则,返回 false 。
示例 1:
输入:arr = [2,6,4,1]
输出:false
解释:不存在连续三个元素都是奇数的情况。
示例 2:
输入:arr = [1,2,34,3,4,5,7,23,12]
输出:true
解释:存在连续三个元素都是奇数的情况,即 [5,7,23] 。
【解题思路】
遍历数组元素,当是奇数时放入定义的列表中,当列表长度大于2了,返回True表示发现三个连续奇数,程序终止。如果是偶数则清空列表,继续循环。
【代码实现】
class Solution:
def threeConsecutiveOdds(self, arr: List[int]) -> bool:
stack = []
for a in arr:
if a % 2 ==1:
stack.append(a)
if len(stack)>2:
return True
else:
stack.clear()
return False
4. 最长连续递增序列
题目来源https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence/
给定一个未经排序的整数数组,找到最长且连续的的递增序列,并返回该序列的长度。
示例 1:
输入: [1,3,5,4,7]
输出: 3
解释: 最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在原数组里被4隔开。
示例 2:
输入: [2,2,2,2,2]
输出: 1
解释: 最长连续递增序列是 [2], 长度为1。
【解题思路】
序列长度小于等于1时,直接返回数组长度作为结果。否则,进行for循环,对列表进行遍历,并判断后一项是否大于前一项,若是,则计数+1,若不是,计数重置为1。for循环中每进行一次判断都要取res和j中的最大值,可以保证循环结束时res的值是数组中最长的连续递增序列的长度。
【代码实现】
class Solution:
def findLengthOfLCIS(self, nums: List[int]) -> int:
if len(nums) <= 1:
return len(nums)
j = 1
res = 0
for i in range(len(nums) - 1):
if nums[i+1] > nums[i]:
j += 1
else:
j = 1
res = max(res, j)
return(res)
5. 将数组分成和相等的三个部分
题目来源 https://leetcode-cn.com/problems/partition-array-into-three-parts-with-equal-sum/
给你一个整数数组 A,只有可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false。
形式上,如果可以找出索引 i+1 < j 且满足 A[0] + A[1] + … + A[i] == A[i+1] + A[i+2] + … + A[j-1] == A[j] + A[j-1] + … + A[A.length - 1] 就可以将数组三等分。
示例 1:
输入:[0,2,1,-6,6,-7,9,1,2,0,1]
输出:true
解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
示例 2:
输入:[0,2,1,-6,6,7,9,-1,2,0,1]
输出:false
示例 3:
输入:[3,3,6,5,-2,2,5,1,-9,4]
输出:true
解释:3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
【解题思路】
- 对列表求和除以3,商quotient不为整数则返回False。
- 创建一个新列表,从头求每一部分的和,求出的第一部分和第二部分,添加到新列表
- 第三部分,就是剩余数组的和了,如果第三部分的和等于quotient,则返回True
【代码实现】
class Solution(object):
def canThreePartsEqualSum(self, A):
total = sum(A)
length=len(A)
quotient = total/3
if quotient % 1 == 0:
s = 0
l = []
for i in range(len(A)):
s += A[i]
if s == quotient:
l.append(s)
s = 0
if len(l) == 2 and i != len(A)-1:
c = total-2*quotient
return c == quotient
return False
参考资料
更多题目请参考这篇博文
https://blog.csdn.net/liuchunming033/article/details/103037171