剑指OFFER 笔记

1 二维数组查找

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 输入: target =7, array =[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]] 输出:True

解答:
注意观察
[[1, 2, 8, 9],
[2, 4, 9, 12],
[4, 7,10, 13],
[6, 8,11, 15]]
每个元素,它的右边的元素都比它大,上面的元素都比它小。
因此,从左下角开始,判断当前元素e是否大于target

if e<target
	该行不存在target元素,向上迭代判断
elif e>=target
	该行可能存在target元素,可以查找

solution:

# -*- coding:utf-8 -*-
class Solution:
    # array 二维列表
    def Find(self, target, array):
        # write code here
        return_val = False
        h = len(array)
        w = len(array[0])
        if w * h > 0:
            search_h = h - 1
            while search_h >=0:
                if array[search_h][0] > target:
                    search_h = search_h -1
                else:
                    for idx in range(0,w):
                        if array[search_h][idx] == target:
                            return True
                        else:
                            continue
                    search_h = search_h - 1
        return return_val
这种有序查找的题型先注意观察,从四个角开始判断如果满足一定条件,该如何查找,是否漏找。判断满足条件直接查找行(列),否则下一行(列)。这一题应该也是可以按照列判断的(相当于矩阵转置了)

2 替换空格

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 "We Are Happy" -> "We%20Are%20Happy"

解答:比较简单
(1) return s.replace(’ ‘, ‘%20’)即可
(2) 将字符串转成数组,对于’ ‘直接转为 r’%20’

    def replaceSpace(self , s ):
        ns = ''
        l = list(s)
        n = len(l)
        for i in range(0,n):
            if l[i] == ' ':
                l[i] = r'%20'
            ns = ns + l[i]
        return ns

或者split成长度更小的列表,然后添加也是可以的

class Solution:
    def replaceSpace(self , s ):
        l = s.split(' ')
        n = len(l)
        ns = ''
        for i in range(0, n):
            ns = ns + l[i]
            if i < n-1 :
                ns = ns + r'%20'
        return ns

3 从尾到头打印列表

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。 {67,0,24,58} -> [58,24,0,67]
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

解答:
python 中的list可以解决,新建一个list,把数据依次填入,然后反向输出即可。

def printListFromTailToHead(self, listNode):
        # write code here
        arrayList=[]
        while listNode:
            arrayList.append(listNode.val)
            listNode=listNode.next
        return arrayList[::-1]
但是有必要复习一下单链表的相关知识和实现。 链表主要包括两个东西,一个是节点,一个是通过节点形成的链表。 节点很简单:
class Node:
    def __init__(self, x):
        self.val = x
        self.next = None

节点包含val、next两个属性,相比于C++不同的地方在于,python中每个变量的名其实就是它的地址,所以把两个节点链接起来直接a.next=b就可以了
但是链表中包含的方法会复杂一些,主要包括链表的遍历、插入节点、删除节点,建议看链接
python单链表的实现
链接中的python链表代码:
代码.

4 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。[1,2,3,4,5,6,7],[3,2,4,1,6,5,7]->{1,2,5,3,4,6,7}

解答:考察二叉树数据结构、二叉树的遍历方法(前序,后续,中序)、二叉树的构建、递归
二叉树的遍历方法根据根D、左L、右R分为前序(DLR),后序(LRD),中序(LDR)

二叉树的构建则是通过递归的方法构建,每次首先根据DLR和LDR的结果,查找根节点的位置(DLR的第一个数),然后根据根节点在LDR的位置,将其分为根节点的左子树和右子树的DLR和LDR结果。迭代上述过程。

在递归中需要明确三件事:(1)每次递归向上的返回和向下的传递对象(2)每次递归需完成的工作(3)递归结束的条件

本题中:

  1. 递归每一步完成的工作:
    (1)通过当前两个DLR和LDR计算根节点
    (2)通过根节点计算节点的左子树与右子树分别的DLR和LDR
    (3)将下级计算获得的左子树的根节点和右子树的根节点链接到当前的根节点
  2. 递归向上级的返回对象:根据当前DLR和LDR计算的根节点;递归向下传递的对象:DLR和LDR
  3. 最后一级递归的停止条件:节点的左子树和右子树都为None

如何写好递归

本题我的答案太繁琐

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    
    def reConstructBinaryTree(self, pre, tin):
        trees_list = (pre, tin)
        head = self.BulidTree(trees_list)
        return head

    def findRoot(self, trees_list):
        if trees_list:
            tree_DLR = trees_list[0]
            if isinstance(tree_DLR, list):
                root = tree_DLR[0]
            elif isinstance(tree_DLR, int):
                root = tree_DLR
            return root

    def findLeftTree(self, trees_list):
        if trees_list:
            tree_DLR = trees_list[0]
            tree_LDR = trees_list[1]
            root = self.findRoot(trees_list)
            idx = tree_LDR.index(root)
            if idx > 0:
                left_trees = (list(tree_DLR[1: idx+1]), list(tree_LDR[0: idx]))
            else:
                left_trees = None

            return left_trees

    def findRightTree(self, trees_list):
        if trees_list:
            tree_DLR = trees_list[0]
            tree_LDR = trees_list[1]
            root = self.findRoot(tree_DLR)
            idx = tree_LDR.index(root)
            if len(tree_DLR) > idx + 1:
                right_trees = (list(tree_DLR[idx + 1: ]), list(tree_LDR[idx + 1: ]))
            else:
                right_trees = None
            return right_trees


    def Process(self, Trees):
        root = self.findRoot(Trees)
        left_trees = self.findLeftTree(Trees)
        right_trees = self.findRightTree(Trees)
        node = TreeNode(root)
        node.left = left_trees
        node.right = right_trees
        pass

    def BulidTree(self, trees_list):
        root = self.findRoot(trees_list)
        if root:
            left_trees = self.findLeftTree(trees_list)
            right_trees = self.findRightTree(trees_list)
            node = TreeNode(root)
            node.left = self.BulidTree(left_trees)
            node.right = self.BulidTree(right_trees)
            return node

    def BuildAndPrintTree(self, pre, tin):
        trees_list = (pre, tin)
        head = self.BulidTree(trees_list)
        return head

看了下答案,一个很优雅的答案,感觉好强(在构建左子树的过程中,list中的左子树的值都被pop掉了,然后构建右子树)。
从刷题到放弃只用了4道。

class Solution:
    def reConstructBinaryTree(self, pre, tin):
        if not pre or not tin:
            return None
        root = TreeNode(pre.pop(0))
        index = tin.index(root.val)
        root.left = self.reConstructBinaryTree(pre, tin[:index])
        root.right = self.reConstructBinaryTree(pre, tin[index + 1:])
        return root
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值