前言:
标题下有配套免费配套资源供大家下载使用。
本文章可结合专栏内的内容一起使用:
力扣Leetcode数组类简单组(python版本)(专栏)http://t.csdnimg.cn/TfPH7
108.将有序数组转换为而二叉平衡树
题目:
题解思路:
本题的二叉搜索树简单来说,就是有一颗树,它的左结点一定比中间结点小,中间结点一定比右边结点小的二叉树,成为二叉搜索树。
由于数组已经是按升序排序的,我们可以采用递归的思想,把数组中间的值作为根结点,然后把中间值左边部分数组递归调用函数,中间的值右边部分也是额外的递归调用。(注意递归出口)看图:
然后递归的把 左边的数组【-10,-3】和 右边的数组【5,9】按照上面的步骤继续构成一颗树:
本题完整代码:
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> [TreeNode]:
# 递归出口,判断nums是否为空,为空返回空结点
if len(nums) == 0:
return None
mid = (len(nums) - 1) // 2
root = TreeNode(nums[mid])
# print('now_mid is :', nums[mid])
root.left = self.sortedArrayToBST(nums[:mid])
root.right = self.sortedArrayToBST(nums[mid + 1:])
return root
可能遇到的问题:
- 递归办法操作的函数一定要有递归出口!
- mid取值可以是中间偏左即(mid = len(nums - 1) 和中间偏右即( mid = len( nums + 1),但是采用中间偏左可以很大程度上避免一些数组越界的问题。
改进的空间:
递归的办法思路简单明了,但是消耗的内存空间很大!不能处理很大的一棵树,即递归深度有限(最大的局限)
这里可以采用不递归的办法来写(任何递归的函数都可以用一种不递归的方式来实现)(留给读者)
118.杨辉三角
题目:
题解思路:
从题目给的图案能看,很明显每一行的首位数字都是 1 ,然后每一行的第 i 个数字的值都是由上一行的第 i - 1个值加上上一行的第 i 个值,知道这个规律就能写代码了。
本题完整代码:
class Solution:
def generate(self, numRows: int) -> List[List[int]]:
new_list = []
# 其他情况:
for numrow in range(1, numRows + 1): # numrow 意思是行数
# 特例
if numrow == 1:
new_list.append([1])
continue
if numrow == 2:
new_list.append([1, 1])
continue
# print(f'new_list{new_list}')
temp_list = [1] # 每行第一个数都是1
# 每一行应该有 n=numrow 个数
for num in range(1, numrow - 1): # 从1循环到numrow-2
old_list = new_list[numrow - 2] # 上一层的数组
temp_list.append(old_list[num - 1] + old_list[num])
temp_list.append(1) # 添加最后一个元素
new_list.append(temp_list)
return new_list
可能遇到的问题:
- 第一行和第二行作为特例特殊处理
- 注意行标和数组下标的范围,不要弄混了
- 每一行的行首和行尾都是特例 1 特殊处理
改进的空间:
这里每一次计算当前层的数值的时候,都用到了上一层的数组,复制数组消耗的空间很大,我们可以多设几个指针指向上一层数组的位置,避免开设temp_list (留给读者)
119.杨辉三角Ⅱ
题目:
题解思路:
本题是上一题的衍生版本,这里的 rowIndex 要求从0开始,我们在 118 题代码的基础上,把for循环的范围变成从 0 开始,并且最后只输出第 rowIndex 行即可!
本题完整代码:
class Solution:
def getRow(self, rowIndex: int) -> List[int]:
new_list = []
# 其他情况:
for numrow in range(0, rowIndex + 1): # 题目最多是33行
# 特例
if numrow == 0:
new_list.append([1])
continue
elif numrow == 1:
new_list.append([1, 1])
continue
else:
temp_list = [1] # 每行第一个数都是1
# 每一行应该有 n=numrow + 1 个数,这里 n 从 0 开始
for num in range(1, numrow): # 只循环n - 2次,首尾都是1,额外处理
old_list = new_list[numrow - 1] # 上一层的数组
temp_list.append(old_list[num - 1] + old_list[num])
temp_list.append(1) # 添加最后一个元素
new_list.append(temp_list)
return new_list[rowIndex]
可能遇到的问题:
- for 循环的范围不清晰,弄混了,导致数组越界
- 最后只用输出一行,不是输出整个杨辉三角
改进的空间:
本题和上一题一样,每次都要新生成一个 temp_list 来存储上一行的值,其实这一步可以省略,节省一定的时间和空间(留给读者)
121.买卖股票的最佳时机
题目:
题解思路:
这题是求一个利润最大的问题,profit = prices[ i ] - prices[ j ],i ,j ( i < j )分别指买入股票的位置和卖出的股票的位置,要使得利润最大,那么买入的时候要尽可能的低价格,卖出的时候要尽可能的高价格。
如下图,我们题目传入一个这样的原始数组:
很直观能看出来我们应该在 1 的位置买入, 在 6 的时候卖出,能得到最大的利润(绿线最长):
具体到代码实现,我们必须要找一个最小值(即买入值),这个最小值可以在 for 循环的同时去寻找,找到最小值我们要决定什么时候去卖,也就是决定我们的利润要最大。
大家可以这么想,我们现在已经买了股票,那么我们先看一下明天的价格,要是明天的利润比今天高,那么我就把股票拿着,等到下一天去卖,每一天都这样直到我们找到一个利润最大值,并且这个利润最大值是我们遍历完整个 prices 数组之后的结果,那么可以确定这个利润是全局最大利润。
本题完整代码:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
# 初始化利润为 0
profit, min_price = 0, inf
for price in prices:
min_price = min(min_price, price)
profit = max(profit, price - min_price)
return profit
改进的空间:
寻找最大最小值的时候可以尝试自己写一下代码,不要老是依赖库函数,用库函数的前提是自己能实现库函数(留给读者)