剑指offer之python篇(四)

061 二叉搜索树的第k个结点

给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回对应节点TreeNode
    def KthNode(self, pRoot, k):
        # write code here
        if not pRoot:
            return None
        ret=[]
        def preNode(node):
            if node ==None:
                return None
            preNode(node.left)
            ret.append(node)
            preNode(node.right)
        preNode(pRoot)
        
        if k>len(ret) or k<1:
            return None
        return ret[k-1]

062 数据流中的中位数

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.littleValueMaxHeap = []
        self.bigValueLittleHeap = []
        self.maxcount = 0
        self.littlecount = 0

    def Insert(self, num):
        # write code here
        if self.maxcount > self.littlecount:
            self.littlecount += 1
            if num < self.littleValueMaxHeap[0]:
                tempNum = self.littleValueMaxHeap[0]
                self.adjustmaxHeap(num)
                self.creatlittleHeap(tempNum)
            else:
                self.creatlittleHeap(num)
        else:
            self.maxcount += 1
            if len(self.littleValueMaxHeap) == 0:
                self.creatmaxHeap(num)
            else:
                if self.bigValueLittleHeap[0] < num:
                    tempNum = self.bigValueLittleHeap[0]
                    self.adjustlittleHeap(num)
                    self.creatmaxHeap(tempNum)
                else:
                    self.creatmaxHeap(num)

    def GetMedian(self,n=None):
        # write code here
        if self.littlecount < self.maxcount:
            return self.littleValueMaxHeap[0]
        else:
            return float(self.littleValueMaxHeap[0] + self.bigValueLittleHeap[0]) / 2

    def creatmaxHeap(self, num):
        self.littleValueMaxHeap.append(num)
        tempIndex = len(self.littleValueMaxHeap) - 1
        while tempIndex:
            parentIndex = (tempIndex - 1) // 2
            if self.littleValueMaxHeap[parentIndex] < self.littleValueMaxHeap[tempIndex]:
                self.littleValueMaxHeap[parentIndex], self.littleValueMaxHeap[tempIndex] = self.littleValueMaxHeap[
                                                                                               tempIndex], \
                                                                                           self.littleValueMaxHeap[
                                                                                               parentIndex]
                tempIndex=parentIndex
            else:
                break

    def adjustmaxHeap(self, num):
        if num < self.littleValueMaxHeap[0]:
            maxHeapLen = len(self.littleValueMaxHeap)
            self.littleValueMaxHeap[0] = num
            tempIndex = 0
            while tempIndex < maxHeapLen:
                leftIndex = tempIndex * 2 + 1
                rightIndex = tempIndex * 2 + 2
                largeIndex = 0
                if rightIndex < maxHeapLen:
                    largeIndex = rightIndex  if self.littleValueMaxHeap[leftIndex] < self.littleValueMaxHeap[rightIndex] else  leftIndex
                elif leftIndex < maxHeapLen:
                    largeIndex = leftIndex
                else:
                    break
                if self.littleValueMaxHeap[tempIndex] < self.littleValueMaxHeap[largeIndex]:
                    self.littleValueMaxHeap[tempIndex], self.littleValueMaxHeap[largeIndex] = self.littleValueMaxHeap[
                                                                                              largeIndex], \
                                                                                          self.littleValueMaxHeap[tempIndex]
                    tempIndex = largeIndex
                else:
                    break

    def creatlittleHeap(self, num):
        self.bigValueLittleHeap.append(num)
        tempIndex = len(self.bigValueLittleHeap) - 1
        while tempIndex:
            parentIndex = (tempIndex - 1) // 2
            if self.bigValueLittleHeap[tempIndex] < self.bigValueLittleHeap[parentIndex]:
                self.bigValueLittleHeap[parentIndex], self.bigValueLittleHeap[tempIndex] = self.bigValueLittleHeap[
                                                                                               tempIndex], \
                                                                                           self.bigValueLittleHeap[
                                                                                               parentIndex]
                tempIndex = parentIndex
            else:
                break

    def adjustlittleHeap(self, num):
        if num < self.bigValueLittleHeap[0]:
            maxHeapLen = len(self.bigValueLittleHeap)
            self.bigValueLittleHeap[0] = num
            tempIndex = 0
            while tempIndex < maxHeapLen:
                leftIndex = tempIndex * 2 + 1
                rightIndex = tempIndex * 2 + 2
                largeIndex = 0
                if rightIndex < maxHeapLen:
                    largeIndex = rightIndex if self.bigValueLittleHeap[rightIndex] < self.bigValueLittleHeap[
                        leftIndex] else  leftIndex
                elif leftIndex < maxHeapLen:
                    largeIndex = leftIndex
                else:
                    break
                if self.bigValueLittleHeap[largeIndex] < self.bigValueLittleHeap[tempIndex]:
                    self.bigValueLittleHeap[tempIndex], self.bigValueLittleHeap[largeIndex] = self.bigValueLittleHeap[
                                                                                              largeIndex], \
                                                                                          self.bigValueLittleHeap[tempIndex]
                    tempIndex = largeIndex
                else:
                    break

063 滑动窗口的最大值

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

# -*- coding:utf-8 -*-
class Solution:
    def maxInWindows(self, num, size):
        # 如果数组 num 不存在,则返回 []
        if not num:
            return []
        # 如果滑动窗口的大小大于数组的大小,或者 size 小于 0,则返回 []
        if size > len(num) or size <1:
            return []

        # 如果滑动窗口的大小为 1 ,则直接返回原始数组
        if size == 1:
            return num

        # 存放最大值,次大值的数组,和存放输出结果数组的初始化
        temp = [0]
        res = []

        # 对于数组中每一个元素进行判断
        for i in range(len(num)):
            # 判断第 i 个元素是否可以加入 temp 中
            # 如果比当前最大的元素还要大,清空 temp 并把该元素放入数组
            # 首先判断当前最大的元素是否过期
            if i -temp[0] > size-1:
                temp.pop(0)
            # 将第 i 个元素与 temp 中的值比较,将小于 i 的值都弹出
            while (len(temp)>0 and num[i] >= num[temp [-1]]):
                temp.pop()
            # 如果现在 temp 的长度还没有达到最大规模,将元素 i 压入
            if len(temp)< size-1:
                temp.append(i)
            # 只有经过一个完整的窗口才保存当前的最大值
            if i >=size-1:
                res.append(num[temp [0]])
        return res

064 矩阵中的路径

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

class Solution:
    def hasPath(self, matrix, rows, cols, path): 
        assistMatrix = [True]*rows*cols 
        for i in range(rows): 
            for j in range(cols): 
                if(self.hasPathAtAStartPoint(matrix,rows,cols, i, j, path, assistMatrix)): 
                    return True 
        return False 
    def hasPathAtAStartPoint(self, matrix, rows, cols, i, j, path, assistMatrix): 
        if not path:
            return True 
        index = i*cols+j 
        if i<0 or i>=rows or j<0 or j>=cols or matrix[index]!=path[0] or assistMatrix[index]==False: 
            return False
        assistMatrix[index] = False 
        if(self.hasPathAtAStartPoint(matrix,rows,cols,i+1,j,path[1:],assistMatrix) or self.hasPathAtAStartPoint(matrix,rows,cols,i-1,j,path[1:],assistMatrix) or self.hasPathAtAStartPoint(matrix,rows,cols,i,j-1,path[1:],assistMatrix) or self.hasPathAtAStartPoint(matrix,rows,cols,i,j+1,path[1:],assistMatrix)):
            return True
        assistMatrix[index] = True 
        return False

065 机器人的运动范围

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

#coding=utf-8
class Solution:
    def judge(self, threshold, i, j):
        # sum(map(int, str(i) + str(j)))这一句简直精髓! 直接得到坐标位置的 位和! i,j是超过1位的数也可以完美解决!
        if sum(map(int, str(i) + str(j))) <= threshold:
            return True
        else:
            return False
 
    def findgrid(self, threshold, rows, cols, matrix, i, j):
        count = 0
        if i<rows and j<cols and i>=0 and j>=0 and self.judge(threshold, i, j) and matrix[i][j] == 0: # matrix[i][j]==0表示没走过这一格
            matrix[i][j] = 1  # 表示已经走过了
            count = 1 + self.findgrid(threshold, rows, cols, matrix, i, j+1) \
            + self.findgrid(threshold, rows, cols, matrix, i, j-1) \
            + self.findgrid(threshold, rows, cols, matrix, i+1, j) \
            + self.findgrid(threshold, rows, cols, matrix, i-1, j)
        return count
 
    def movingCount(self, threshold, rows, cols):
        matrix = [[0 for i in range(cols)] for j in range(rows)]
        count = self.findgrid(threshold, rows, cols, matrix, 0, 0)
        print(matrix)
        return count
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值