中级农民
- 积分
- 104
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2018-3-17
- 最后登录
- 1970-1-1
|
Day 12:
Q1. Different Ways to Add Parenthesis 【Medium】
题目理解:1)输入:一个字符串input,包含数字和操作符
2)输出:整数列表,表示在input 中任意加入括号后能得到的所有整数解
3)有效操作符包括:’+’、‘-’、‘*’。
4)输出的结果唯一,不计顺序
解决方法: 递归。和昨天的Word Break类似,将整个输入从每个操作符分别分成左右两部分,并分别进行递归调用原函数计算,之后将左右两部分结果保留后进行笛卡尔积操作,并将循环的所有结果保存在ans中一起输出即可。一开始想的时候觉得较为复杂,但想明白并进行实际操作之后,会发现实现起来还比较简单,代码也比较简洁。具体代码实现过程如下(python):
class Solution(object):
def diffWaysToCompute(self, input):
ans = []
n = len(input)
for i in range(0, n):
op = input[i]
if op in {'+', '-', '*'}:
left = input[:i]
right = input[i+1:]
L = self.diffWaysToCompute(left)
R = self.diffWaysToCompute(right)
for l in L:
for r in R:
ans.append(self.f(l,r,op))
if len(ans) == 0:
ans.append(int(input))
return ans
def f(self, l, r, op):
if op == '+':
return l+r
if op == '-':
return l-r
if op == '*':
return l*r
Q2. Binary Tree Level Order Traversal 【Medium】
题目理解:1)输入:二叉树(root)
2)输出:List[List[int]],表示给定二叉数按照每一层进行打印的结果
3)输出中每个整数表示原二叉树中每个节点的值,打印顺序为从上到下,从左到右,中间的空节点全部省略。
解决方法:1)BFS。利用宽度优先搜索的方式跟题目的描述最为接近。利用两个辅助list分别记录当前层currL和下一层nextL的节点(先进先出相当于queue),按照逐层遍历的方式,进行逐层打印即可。具体实现方式如下(python):
class Solution(object):
def levelOrder(self, root):
currL = []
nextL = []
if not root:
return []
ans = []
currL.append(root)
while currL:
ans.append([])
for c in currL:
ans[-1].append(c.val)
if c.left:
nextL.append(c.left)
if c.right:
nextL.append(c.right)
currL = nextL
nextL = []
return ans
2)DFS。和之前遇到的二叉树问题类似,因为需要对整棵树进行遍历,因此除了BFS之外同样可以利用DFS进行深度优先搜索。利用递归的方式进行先序遍历,同时需要引入一个辅助变量level或者height进行层与层之间的传递。这道题中DFS和BFS的运行时间差不多都是24ms,BFS更易理解,DFS的代码更加简洁。具体实现过程如下(python):
class Solution(object):
def levelOrder(self, root):
ans = []
self.dfs(root, 0, ans)
return ans
def dfs(self, root, level, ans):
if not root:
return []
if len(ans) <= level:
ans.append([])
ans[level].append(root.val)
self.dfs(root.left, level+1, ans)
self.dfs(root.right, level+1, ans)
相似题目:Leetcode 637. Average of Levels in Binary Tree。前几天的简单题目中出现过。
Q3. Maximum Binary Tree 【Medium】
题目理解:1)输入:整数列表nums
2)输出: 二叉数(root)
3)题目给出了一种将list转变为二叉树的规则:list中的最大值为根节点,最大值左边的元素为左子树,右边为右子树,其左右子树的构成规则同上。
解决方法: 递归。根据题目描述,比较容易想到递归,因为每个子树的构成规则和整个列表相同,因此只要一开始先找到最大值构建根节点,之后对list的左半部分和右半部分分别递归调用解函数返回作为左右子树即可。注意要考虑corner case进行必要的保护操作。具体实现如下(python):
class Solution(object):
def constructMaximumBinaryTree(self, nums):
if not nums:
return
root = TreeNode(0)
rootIndex = nums.index(max(nums))
root.val = max(nums)
left = nums[:rootIndex]
right = nums[rootIndex+1:]
root.left = self.constructMaximumBinaryTree(left)
root.right = self.constructMaximumBinaryTree(right)
return root
Q4. Word Search 【Medium】
题目理解:1)输入:二维字符矩阵board,和一个字符串word
2)输出:bool结果,表示是否可以在board中找到word
3)规则:用board中的字母构成单词时,每个字符只能向上下左右四个方向的相邻元素前进,且同一个位置的字符不能重复使用。起始位置未指定
解决方法: DFS。因为题目需要找整个word是否出现,相当于深度确定,且扩展方向为上下左右四个方向,较为复杂,因此我们采用DFS进行递归。我们需要两个大的步骤,一是要定义辅助函数search,进行递归条件的描述并完成递归过程;而是要通过对board进行直接循环寻找可能的起始位置,再call自定义的search函数。需要注意的是,这道题目的边界情况较多,且由于同一个位置不能多次使用,因此在search中需要进行回溯。具体实现过程如下(python):
class Solution(object):
def exist(self, board, word):
m = len(board)
if m == 0:
return False
n = len(board[0])
l = len(word)
for j in range(0, m):
for k in range(0, n):
if self.search(j, k, board, 0, word):
return True
return False
def search(self, x, y, board, i, word):
m = len(board)
if m == 0:
return False
n = len(board[0])
l = len(word)
if l > m*n: return False
if x<0 or x>m-1 or y<0 or y>n-1:
return False
if word[i] != board[x][y]:
return False
if i == l-1:
return True
curr = board[x][y]
board[x][y] = '0'
ans = self.search(x+1, y, board, i+1, word) or self.search(x-1, y, board, i+1, word) or self.search(x, y+1, board, i+1, word) or self.search(x, y-1, board, i+1, word)
board[x][y] = curr
return ans
Q5. Find Minimum in Rotated Sorted Array 【Medium】
题目理解:1)输入:整数列表nums,满足进行rotate操作后会变成一个排好序的列表,且nums中无重复元素
2)输出:整数,表示nums中的最小值
3)输入的例子:nums = [4, 5, 6, 7, 1, 2, 3][1, 2, 3, 4, 5, 6, 7]
解决方法:1)直接排序找第一个元素/直接返回最小值。运行时间较长
2)for 循环直接遍历nums,找到第一个nums[i] < nums[i-1]输出nums[i],若循环结束也没找到,说明nums为排好序的列表,直接返回nums[0]
3)二分法。最小值一定出现在非连续上升序列的一半中,或者就是第一个元素。因此每次循环中只需要对mid和right进行比较即可。具体实现如下(python):
class Solution(object):
def findMin(self, nums):
n = len(nums)
if n<1: return []
left = 0
right = n-1
while left < right -1:
mid = left+(right-left)/2
if nums[mid] < nums[right]:
right = mid
continue
else:
left = mid
return min(nums[left], nums[right])
|
|