剑指offer(一)

二维数组中的查找

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

# -*- coding:utf-8 -*-
class Solution:
    # array 二维列表
    def Find(self, target, array):
        # write code here
        for temparr in array:
            low = 0
            high = len(temparr)-1
            while(low<=high):
                mid = (low+high)//2
                if (temparr[mid]==target):
                    return True
                elif temparr[mid]<target:
                    low = mid+1
                else:
                    high = mid -1
        return False     #218ms

    def Find1(self, target, array):
        row = len(array)
        col = len(array[0])
        i = row-1
        j = 0
        while(i>=0 and j<col):
            if(array[i][j]==target):
                return True
            elif array[i][j]> target:
                i -=1
            else:
                j +=1
        return  False         #419ms

从尾到头打印列表

输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def __init__(self):
        self.res=[]

    def printListFromTailToHead(self, listNode):

        if listNode is not None:

            self.printListFromTailToHead(listNode.next)
            self.res.append(listNode.val)

        return self.res         #26ms


        # if listNode is None:
        #     return []
        # return self.printListFromTailToHead(listNode.next) + [listNode.val]

    def printListFromTailToHead1(self, listNode):


        return self.res         #26ms

重建二叉树

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

# -*- coding:utf-8 -*-
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    # 返回构造的TreeNode根节点
    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  #76ms

用两个栈实现队列

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

入队时,判断stack1是否为空,如不为空,将元素压入stack1;如为空,先将stack2元素倒回stack1,再将新元素压入stack1

出队时,判断stack2是否为空,如不为空,则直接弹出顶元素;如为空,则将stack1的元素逐个“倒入”stack2,
把stack1最后一个元素弹出并出队。

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

    def push(self, node):
        if len(self.stack1)==0:
            while len(self.stack2)>0:
                self.stack1.append(self.stack2.pop())
        self.stack1.append(node)

    def pop(self):
        if len(self.stack2)==0:
            while len(self.stack1)>0:
                self.stack2.append(self.stack1.pop())

        return self.stack2.pop()

# return xx
s = Solution()
print(s.push(1))
print(s.push(2))
print(s.push(3))
print(s.pop())
print(s.pop())
print(s.push(4))
print(s.pop())
print(s.push(5))
print(s.pop())
print(s.pop())

旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        if len(rotateArray)==0:
            return 0
        min = rotateArray.pop(0)
        for i in range(len(rotateArray)):
            if rotateArray[i]<min:
                min = rotateArray[i]
        return min                 #671ms

    def minNumberInRotateArray1(self, rotateArray):
        low = 0
        high = len(rotateArray)-1
        while(low<high):
            if high-low==1:
                return rotateArray[high]
            mid = (low+high)//2
            if rotateArray[mid]>=rotateArray[high]:
                low = mid
            else:
                high = mid

        return rotateArray[high]   #1000ms

s=Solution()
print(s.minNumberInRotateArray1([2,3,4,5,1]))

矩形覆盖

我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

class Solution:
    def rectCover(self, number):
        if number<1:
            return 0
        if number==1:
            return 1
        if number==2:
            return 2
        a = 1
        b = 2
        for i in range(2,number):
            temp = a
            a = b
            b = a+temp
        return b


        # return self.rectCover(number - 1) +self.rectCover(number - 2)

二进制中1的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

因为python的int是无线精度的,c++的int是32为的,所以python的负数相当于前面有无限个1,要对python的负数做处理

class Solution:
    def NumberOf1(self, n):
        # f=1
        # c = 0
        # for _ in range(32): #因为python是无限精度,所以不能while(flag),会一直有循环下去,只能截取32位
        #     if f&n>=1:
        #         c+=1
        #     f = f<<1
        # return c

        c = 0
        if n<0:
            n = n&0xffffffff
        while n:
            c += 1
            n &= n-1
        return c

数值的整数次方

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

*1.当底数为0且指数<0时

*会出现对0求倒数的情况,需进行错误处理,设置一个全局变量;

*2.判断底数是否等于0

*由于base为double型,不能直接用==判断

*3.优化求幂函数

*当n为偶数,

a^n = a^{n/2}*a^{n/2}

*当n为奇数,

a^n = a^{(n-1)/2}*a^{(n-1)/2}*a

*时间复杂度O(logn)

class Solution:
    def Power(self, base, exponent):
        if base == 0:
            return 0
        if exponent == 0:
            return 1
        # if exponent<0:
        #     res = 1
        #     for i in range(-exponent):
        #         res *= base
        #     return 1/res
        # if exponent>0:
        #     res = 1
        #     for i in range(exponent):
        #         res *= base
        #     return res           #30ms

        #优化幂运算
        e = abs(exponent)
        res = 1
        temp = base
        while(e>0):
            if e&1 ==1:
                res *= temp

            e = e>>1
            temp = temp*temp
        return res if exponent>0 else 1/res    #41ms

调整数组顺序(可再优化)

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,
所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

class Solution:
    def reOrderArray(self, array):
        length = len(array)-1
        i=0  #总是指向第一个偶数
        j=0
        while(j<length and i<length):
            while(i<length and array[i]%2==1):
                i+=1
            j = i+1
            while(j<length and array[j]%2==0):
                j+=1
            if(j==length and array[j]%2==0):break
            temp=array[j]
            for k in range(j-1,i-1,-1):
                array[k+1]=array[k]
            array[i]=temp
        return array
s = Solution().reOrderArray([1,2,3,4,5,6,7])
print(s)

链表中倒数第K个节点

输入一个链表,输出该链表中倒数第k个结点。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def FindKthToTail(self, head, k):
        # if head is None or k <= 0:
        #     return None
        # index = 0
        # node_index = head
        # while(node_index.next is not None):
        #     if index < k-1:
        #         index +=1
        #         node_index = node_index.next
        #
        # if index< k-1:
        #     return None
        # k_index = head
        #
        # while(node_index.next is not None):
        #     k_index = k_index.next
        #     node_index = node_index.next
        # return k_index

        if head is None or k <= 0:
            return None
        index = 0
        node_index = head
        k_index = head

        while(node_index.next is not None):
            node_index = node_index.next
            index +=1
            if index >= k-1:
                k_index = k_index.next
        if index >=k :
            return None
        else:
            return k_index

反转链表

输入一个链表,反转链表后,输出新链表的表头。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        if pHead is None or pHead.next is None:
            return pHead

        pre = None
        curr = pHead

        while curr is not None:
            temp = curr.next
            curr.next = pre
            pre = curr
            curr = temp

        return pre

合并两个有序列表

输入两个单调递增的链表,输出两个链表合成后的链表,
当然我们需要合成后的链表满足单调不减规则。

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2):
        if pHead1 is None:
            return pHead2
        if pHead2 is None:
            return pHead1

        # 递归方法
        # if pHead1.val<=pHead2.val:
        #     listNode = pHead1
        #     listNode.next = self.Merge(pHead1.next, pHead2)
        #
        # else:
        #     listNode = pHead2
        #     listNode.next = self.Merge(pHead1,pHead2.next)
        # return listNode

        #非递归方法
        listNode = ListNode(0)
        p = listNode
        while pHead1 is not None and pHead2 is not None:
            if pHead1.val <= pHead2.val:
                listNode.next = pHead1
                pHead1 = pHead1.next
            else:
                listNode.next = pHead2
                pHead2 = pHead2.next
            listNode = listNode.next

        if pHead1 is not None:
            listNode.next = pHead1
        if pHead2 is not None:
            listNode.next = pHead2

        return p.next

数的子结构

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        if pRoot1 is None or pRoot2 is None:
            return False

        return self.HasSubtree(pRoot1.left,pRoot2) |\
                self.HasSubtree(pRoot1.right,pRoot2)|\
                self.isSubtree(pRoot1,pRoot2)


    def isSubtree(self,node1,node2):
        if node2 is None:
            return True

        if node1 is None:
            return False

        if node1.val == node2.val:
            return self.isSubtree(node1.left,node2.left) and\
                self.isSubtree(node1.right,node2.right)
        else:
            return False

二叉树的镜像

操作给定的二叉树,将其变换为源二叉树的镜像。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        # write code here
        if root is None:
            return root
        temp = root.left
        root.left = self.Mirror(root.right)
        root.right = self.Mirror(temp)
        return root

顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):

        res = []
        while matrix:
            res += matrix.pop(0)
            if matrix and matrix[0]:
                for row in matrix:
                    res.append(row.pop())
            if matrix:
                res += matrix.pop()[::-1]
            if matrix and matrix[0]:
                for row in matrix[::-1]:
                    res.append(row.pop(0))
        return res

包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
思路:构建一个辅助栈用来存储当前的最小值

class Solution:
    def __init__(self):
        self.mainStack = []
        self.minStack = []

    def push(self, node):
        min = self.min()
        if not min or node < min:

            self.minStack.append(node)
        else:
            self.minStack.append(min)

        self.mainStack.append(node)


    def pop(self):
        if self.mainStack:
            self.minStack.pop()
            return self.mainStack.pop()

    def top(self):
        if self.mainStack:
            return self.mainStack[-1]

    def min(self):
        if self.minStack:
            return self.minStack[-1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值