python剑指offer系列-leetcode剑指offer系列专题

03. 数组中重复的数字 简单

题目链接
分析
题目难度为简单,最直白的方法就是开辟哈希表记录访问过的数字
此题可以做到 O ( 1 ) O(1) O(1),利用题目中的信息,一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。
假设n为5,按照题意给定一个没有重复数字的数组

index 0 1 2 3 4
data 3 1 4 2 0

可以看到,数据本身是索引的一个置换(题目给的信息),数据本身也可以当索引来用
一个有重复数字的数组

index 0 1 2 3 4
data 3 4 4 0 2

如果把数据当索引来用,一定会出现重复访问,要做的就是记录已经访问的数据
code

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        for i in range(len(nums)):
        	# i是原索引,abs(nums[i])是数据,这里当作新索引来用
        	# 若出现重复访问,返回答案
            if nums[abs(nums[i])] < 0:
                return abs(nums[i])
            else:
            	# 次数使用原数据的负数来表示,该数据已经被访问
                nums[abs(nums[i])] = -1 * nums[abs(nums[i])]
        # 到了这一步,重复数字是一定0
        return 0

04. 二维数组中的查找

分析
没啥可讲的,想通了就通了
code

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        if not matrix or not matrix[0]:
            return False
        rowIndex, colIndex = 0, len(matrix[0])-1
        while rowIndex < len(matrix) and colIndex >=0:
            if matrix[rowIndex][colIndex] == target:
                return True
            elif matrix[rowIndex][colIndex] > target:
                colIndex -= 1
            else:
                rowIndex += 1
                
        return False

07. 重建二叉树

分析
给定前序遍历和中序遍历的结果能确定一颗唯一的二叉树。
关键在于能根据二叉树的前序遍历和中序遍历,确定左右子树的前序遍历和中序遍历。code时唯一要注意的就是何时递归结束
code

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if not preorder:
            return None
       
        def zp_buildTree(preorder: list, pr_l, pr_r, inorder: list, in_l, in_r):
            if pr_l > pr_r or in_l > in_r:
                return None

            root = TreeNode(preorder[pr_l]) # 构建根结点
            root_index = inorder.index(preorder[pr_l])  # 找到根结点在中序的位置
            L = root_index - in_l
            R = in_r - root_index # 左右子树的长度

            root.left = zp_buildTree(preorder, pr_l+1, pr_l+L, inorder, in_l, root_index-1)
            root.right = zp_buildTree(preorder, pr_l+L+1, pr_r, inorder, root_index+1, in_r)
            return root

        return zp_buildTree(preorder, 0, len(preorder)-1, inorder, 0, len(inorder)-1)

08:二叉树的下一个节点

牛客
分析
这里题目要求是中序遍历(左中右)的下一个节点。
不用关系p是否有左子树,中序遍历中,p的左子树一定都在p前面
给定节点p,若p有右子树,p在中序遍历中的下一个节点就是自己右子树中序遍历结果的第一个节点。
若p没有右子树,那么p右两种可能:
1,p是某棵子树的左子树,p在中序遍历中的下一个节点就是自己的父节点
2,p是某棵子树的右子树,这就要一直向上寻找p的父节点,祖父节点等等(广义上都是父节点)。何时截止,直到当前这个父节点表示的子树是某棵树的左子树,那么下一个父节点就是p在中序遍历中的下一个节点。
使用非递归算法中序遍历遍历一遍二叉树,这个过程就很清楚了。
code

class Solution:
    def GetNext(self, p):
        # write code here
        if p.right:
            p = p.right
            while p.left:
                p = p.left
            return p 
        while p.next and p.next.right == p:
            p = p.next
        return p.next

09-1. 用两个栈实现队列

分析
这里的栈,只支持栈尾 push 和 pop,python的列表虽然有pop(0)这个功能,但这里不能用。
code

class CQueue:

    def __init__(self):
        self.stack1 = []
        self.stack2 = []


    def appendTail(self, value: int) -> None:
        self.stack1.append(value)


    def deleteHead(self) -> int:
        if not self.stack1 and not self.stack2:
            return -1
        elif self.stack2:
            return self.stack2.pop()
        else:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
            return self.stack2.pop
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值