python版:剑指offer刷题

1. 二维数组中的查找

Q: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

时间复杂度O(n)

a = [[1, 2, 8, 9], [2, 4, 9, 12], [4, 7, 10, 13], [6, 8, 11, 15]]


class Solution:
    # 二维列表数据查找

    def find(self, target, array):
        if array == []:
            return False
        else:
            array_row = len(array)
            array_col = len(array[0])
            i, j = 0, array_col - 1
            while i < array_row and j >= 0:
                if array[i][j] > target:
                    j -= 1
                elif array[i][j] < target:
                    i += 1
                else:
                    return '有数值%s' % target
            else:
                return '没有数值%s' % target


test = Solution()
print(test.find(10, a))
2. 替换空格

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

class Solution:
    # 将空格替换为%20
    def replace_space(self, s):
        s_list = s.split(' ')
        result = '%20'.join(s_list)
        return result

test=Solution()
print(test.replace_space('We Are Happy'))
3. 从头到尾打印链表

**Q:**输入一个链表的头结点,从尾到头反过来打印出每个节点的值

不知道怎么做测试

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        # write code here
        if listNode == None:
            return []
        result = []
        while listNode != None:
            result.append(listNode.val)
            listNode = listNode.next
        return result[::-1]
4. 二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
在这里插入图片描述
方法一:

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        for row in matrix:
            for column in row:
                if column==target:
                    return True
        return False

方法2:

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        # 判断是否为空
        if len(matrix)==0 or len(matrix[0])==0:
            return False
        
        # 矩阵的尺寸
        height=len(matrix)
        width=len(matrix[0])

        # 右上角开始搜索
        row=0
        col=width-1
        while row<height and col>=0:
            if matrix[row][col] > target:
                col-=1
            elif matrix[row][col] < target:
                row+=1
            elif matrix[row][col] == target:
                return True
        return False
5. 剪绳子

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
在这里插入图片描述

"""
绳子的长度为n厘米
dp[i]表示长度为i厘米绳子的最大乘积,例如:当dp[1]表示长度为1厘米绳子的最大乘积
j表示切割点,例如j=1表示在1厘米处切割
tmp表示在当前j厘米处切割后的最大乘积
max(j,dp[j])表示在j厘米处切割后,比较j和dp[j]的大小,
    如果j<dp[j]表示j小于j的最大乘积,说明j可以将继续分割;
    如果j>dp[j]表示j大于j的最大乘积,说明j不需要继续分割
max(i-j,dp[i-j])对剩余的i-j厘米的绳子比较i-j和dp[i-j]的大小
    如果i-j<dp[i-j]表示i-j小于i-j的最大乘积,说明i-j可以继续分割;
    如果i-j>dp[i-j]表示i-j大于i-j的最大乘积,说明i-j不可以继续分割;
"""

class Solution:
    def cuttingRope(self, n: int) -> int:
        dp = [0 for _ in range(n+1)]
        dp[1] = 1
        # 因为i=0和1意义不大,所以从2开始,dp[0]=0,dp[1]=1
        for i in range(2,n+1):
            # 切割点j只需要取到总长度的一半即可
            for j in range(1,i//2+1):
                tmp = max(j,dp[j])*max(i-j,dp[i-j])
                dp[i] = max(dp[i],tmp)
        return dp[-1]
6. 找出数组中重复的数字

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
在这里插入图片描述

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        new_list=set()
        for i in nums:
            if i in new_list:
                return i
            else:
                new_list.add(i)
        return -1
7. 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字
在这里插入图片描述

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if len(inorder)==0:
            return None
        
        # 构建二叉树
        root = TreeNode(preorder[0])
        # 获取根节点在中序遍历中的位置
        num = inorder.index(preorder[0])
        # 左子树
        root.left = self.buildTree(preorder[1:num+1],inorder[:num])
        # 右子树
        root.right = self.buildTree(preorder[num+1:],inorder[num+1:])
        return root

在这里插入图片描述

9. 用两个栈实现队列

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
在这里插入图片描述

class CQueue:

    def __init__(self):
        self.A,self.B=[],[]

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

    def deleteHead(self) -> int:
        if self.B: return self.B.pop()
        elif not self.A: return -1
        else:
            while self.A:
                self.B.append(self.A.pop())
            return self.B.pop()
10. 旋转数组的最小数字

在这里插入图片描述

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        if numbers == '':
            return []
        else:
            left = 0
            right = len(numbers) - 1
            while left < right:
                mid = (left + right) // 2
                if numbers[mid] > numbers[right]:
                    left = mid + 1
                elif numbers[mid] < numbers[right]:
                    right = mid
                else:
                    right -= 1
            return numbers[left]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值