题目描述1:33.二叉搜索树的后序遍历序列   难度:中等

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

参考以下这颗二叉搜索树:

     5

    / \

   2   6

  / \

 1   3

示例 1:

输入: [1,6,3,2,5]

输出: false

示例 2:

输入: [1,3,2,6,5]

输出: true

解题思路:

层序遍历

Python代码:

class Solution:    def verifyPostorder(self, postorder: List[int]) -> bool:        if postorder is None or len(postorder) == 0:            return True        n = len(postorder)        # 根结点        root = postorder[-1]        # 在二叉搜索树中左子树的结点小于根结点        i = 0        for i in range(n):            if postorder[i] > root:                break        # 在二叉搜索树中右子树的结点小于根结点        for j in range(i,n-1):            if postorder[j] < root:                return False        # 判断左子树是不是二叉搜索树        left = True        if i > 0:            left = self.verifyPostorder(postorder[:i])  # 左闭右开        # 判断右子树是不是二叉搜索树        right = True        if i < n-1:            right = self.verifyPostorder(postorder[i:-1])        return left and right

题目描述2:34.二叉树中和为某一值的路径   难度:中等

输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。

示例:

给定如下二叉树,以及目标和 sum = 22,

              5

             / \

            4   8

           /   / \

          11  13  4

         /  \    / \

        7    2  5   1

返回:

[

   [5,4,11,2],

   [5,8,4,5]

]

解题思路:

DFS + 回溯

BFS 迭代

Python代码:

#方法1codeclass Solution:    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:            res,path = [] ,[]        def dfs(root,target):            if not root:return []            target -= root.val            path.append(root.val)            if not root.left and not root.right and target == 0:                res.append(path[:]) #res.append(list(path))            dfs(root.left,target)            dfs(root.right,target)            path.pop()        dfs(root,sum)        return res#方法2codeclass Solution:    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:        if not root: return []        queue = [(root, root.val, [root.val])]        res = []        while queue:            node, val, temp = queue.pop(0)            if val == sum and not node.left and not node.right: res.append(temp)            if node.left:                queue.append((node.left, val + node.left.val, temp+[node.left.val]))            if node.right:                queue.append((node.right, val + node.right.val , temp+[node.right.val]))        return res

题目描述3:35.复杂链表的复制   难度:中等

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

示例 1:

python list按行输出到txt python把list输出为树_int转化为list python

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]

输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例 2:

python list按行输出到txt python把list输出为树_python list按行输出到txt_02

输入:head = [[1,1],[2,1]]

输出:[[1,1],[2,1]]

示例 3:

python list按行输出到txt python把list输出为树_List_03

输入:head = [[3,null],[3,0],[3,null]]

输出:[[3,null],[3,0],[3,null]]

示例 4:

输入:head = []

输出:[]

解释:给定的链表为空(空指针),因此返回 null。

解题思路:

1.迭代

2.递归

Python代码:

#方法1code"""# Definition for a Node.class Node:    def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):        self.val = int(x)        self.next = next        self.random = random"""class Solution:    def copyRandomList(self, head: 'Node') -> 'Node':        if not head:return        dic = {}        # 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射        cur = head        # 构建新节点的 next 和 random 指向        while cur:            dic[cur] = Node(cur.val)            cur = cur.next        cur  =head        while cur:            dic[cur].next = dic.get(cur.next)            dic[cur].random = dic.get(cur.random)            cur = cur.next        # 返回新链表的头节点        return dic[head]#方法2codeclass Solution:    def copyRandomList(self, head: 'Node') -> 'Node':        def dfs(head):            if not head:return None            if head in visited:                return visited[head]            #创建新结点            copy = Node(head.val)            visited[head] = copy            copy.next = dfs(head.next)            copy.random = dfs(head.random)            return copy        visited = {}        return dfs(head)

题目描述4:36.二叉搜索树中与双向链表   难度:中等

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

为了让您更好地理解问题,以下面的二叉搜索树为例:

python list按行输出到txt python把list输出为树_python list按行输出到txt_04

我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。

python list按行输出到txt python把list输出为树_python list按行输出到txt_05

特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

解题思路:

中序遍历

Python代码:

#方法1codeclass Solution:    def treeToDoublyList(self, root: 'Node') -> 'Node':        if not root:return        def dfs(cur):            if not cur: return            dfs(cur.left) # 递归左子树            if self.pre:   #修改节点引用                self.pre.right,cur.left = cur,self.pre            else: #记录头节点                self.head = cur            self.pre = cur #保存cur            dfs(cur.right) #递归右子树           self.pre =None        dfs(root)        self.head.left,self.pre.right = self.pre,self.head        return self.head

题目描述5:37.序列化二叉树   难度:困难

请实现两个函数,分别用来序列化和反序列化二叉树。

示例: 

你可以将以下二叉树:

    1

   / \

  2   3

     / \

    4   5

序列化为 "[1,2,3,null,null,4,5]"

解题思路:

Python代码:

# Definition for a binary tree node.# class TreeNode(object):#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Codec:    def serialize(self, root):        if not root: return "[]"        queue = collections.deque()        queue.append(root)        res = []        while queue:            node = queue.popleft()            if node:                res.append(str(node.val))                queue.append(node.left)                queue.append(node.right)            else: res.append("null")        return '[' + ','.join(res) + ']'    def deserialize(self, data):        if data == "[]": return        vals, i = data[1:-1].split(','), 1        root = TreeNode(int(vals[0]))        queue = collections.deque()        queue.append(root)        while queue:            node = queue.popleft()            if vals[i] != "null":                node.left = TreeNode(int(vals[i]))                queue.append(node.left)            i += 1            if vals[i] != "null":                node.right = TreeNode(int(vals[i]))                queue.append(node.right)            i += 1        return root# Your Codec object will be instantiated and called as such:# codec = Codec()# codec.deserialize(codec.serialize(root))

题目描述6:38.字符串的排列   难度:中等

输入一个字符串,打印出该字符串中字符的所有排列。

你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

示例:

输入:s = "abc"

输出:["abc","acb","bac","bca","cab","cba"]

解题思路:

回溯算法

Python代码:

class Solution:    def permutation(self, s: str) -> List[str]:        s = list(s)        res = []        def dfs(x):            if x == len(s):                res.append(''.join(s))    #添加排列方案                return             repeat = []            for i in range(x,len(s)):                if s[i] in repeat:continue #重复,因此剪枝                repeat.append(s[i])                s[x],s[i] = s[i],s[x]       #交换,将c[i]固定在第x位                dfs(x+1)                    #开始国定第x+1位字符                s[i],s[x] = s[x],s[i]       #恢复交换        dfs(0)        return res

题目描述7:39.数组中出现次数超过一半的数字   难度:简单

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]

输出: 2

解题思路:

Python代码:

class Solution:    def majorityElement(self, nums: List[int]) -> int:        # nums.sort()        # return nums[len(nums)//2]        dicts = {}        for i in nums:            dicts[i] = dicts.setdefault(i,0)            dicts[i] += 1            if dicts[i] > len(nums)/2:                return i

题目描述8:40.最小的k个数   难度:简单

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

示例 1:

输入:arr = [3,2,1], k = 2

输出:[1,2] 或者 [2,1]

示例 2:

输入:arr = [0,1,2,1], k = 1

输出:[0]

解题思路:

几种排序算法(待总结):快排、堆排、计数排序

Python代码:

class Solution:    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:        arr.sort()        return arr[:k]

题目描述9:41.数据流中的中位数   难度:困难

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

例如,

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:

void addNum(int num) - 从数据流中添加一个整数到数据结构中。

double findMedian() - 返回目前所有元素的中位数。

示例 1:

输入:

["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"]

[[],[1],[2],[],[3],[]]

输出:[null,null,null,1.50000,null,2.00000]

示例 2:

输入:

["MedianFinder","addNum","findMedian","addNum","findMedian"]

[[],[2],[],[3],[]]

输出:[null,null,2.00000,null,2.50000]

解题思路:

堆排序(待总结),使用堆排序

Python代码:

class MedianFinder:    def __init__(self):        """        initialize your data structure here.        """        self.res = []            def addNum(self, num: int) -> None:        self.res.append(num)    def findMedian(self) -> float:        self.res.sort()        if len(self.res)%2 == 1:            return self.res[len(self.res)//2]        else:            return (self.res[len(self.res)//2]+self.res[len(self.res)//2-1])/2

题目描述10:42.连续子数组的最大和   难度:简单

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。

要求时间复杂度为O(n)。

示例1:

输入: nums = [-2,1,-3,4,-1,2,1,-5,4]

输出: 6

解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

解题思路:

动态规划求解

1.定义当前最大连续子序列和cur_sum=0,最大子序和res=nums[0]。

2.对数组进行遍历,对于nums[i],存在两种情况:

(1) 若当前最大连续子序列和cur_sum>0,说明cur_sum对后续结果有着正向增益,即能使后继结果继续增大,则继续加和:cur_sum=cur_sum+num[i]。

(2)若当前最大连续子序列和cur_sum<=0,说明cur_sum对后续结果没有增益或负向增益,即若存在更大的加和,一定是从下一元素开始,加上cur_sum,只会使结果更小。因此,令cur_sum更新为nums[i]。

更新最大子序和res=max(res,cur_sum),始终保留最大结果。

python list按行输出到txt python把list输出为树_int转化为list python_06

Python代码:

class Solution:    def maxSubArray(self, nums: List[int]) -> int:              cur_sum = 0     #当前最大连续子序列和        res = nums[0]   #最大连续子序列和        for i in range(len(nums)):            if cur_sum>0:                cur_sum += nums[i]            else:                cur_sum = nums[i]            res = max(res,cur_sum)        return res class Solution:    def maxSubArray(self, nums: List[int]) -> int:        # 动态规划dp[i],前i个数组的最大值和, dp[i]必须包含nums[i]        dp = [0 for _ in range(len(nums))]        dp[0] = nums[0]        # 状态转移方程 dp[i] = dp[i-1] + nums[i] ;if dp[i-1] >= 0        #            dp[i] = nums[i] ;if dp[i-1] < 0        for i in range(1,len(nums)):            if dp[i-1] < 0:                dp[i] = nums[i]            else:                dp[i] = dp[i-1] + nums[i]        return max(dp)  #优化  class Solution:    def maxSubArray(self, nums: List[int]) -> int:        for i in range(1, len(nums)):            nums[i] += max(nums[i - 1], 0)        return max(nums)