剑指offer题目

剑指offer

链表(8道):

三:从尾到头打印链表
十四:链表中倒数第k个结点
十五:反转链表
十六:合并两个排序的链表
二十五:复杂链表的复制
三十六:两个链表的第一个公共结点
五十五:链表中环的入口结点
五十六:删除链表中重复的结点

二叉树(12道):

四:重建二叉树
十七:树的子结构
十八:二叉树的镜像
二十二:从上往下打印二叉树
二十四:二叉树中和为某一值的路径
三十八:二叉树的深度
三十九:平衡二叉树
五十七:二叉树的下一个结点
五十八:对称的二叉树
五十九:按之字顺序打印二叉树
六十:把二叉树打印成多行
六十一:序列化二叉树

二叉搜索树(3道):

二十三:二叉搜索树的后序遍历序列
二十六:二叉搜索树与双向链表
六十二:二叉搜索树的第k个结点

数组(11道):

一:二维数组中的查找
六:旋转数组的最小数字
十三:调整数组顺序使奇数位于偶数前面
二十八:数组中出现次数超过一半的数字
三十:连续子数组的最大和
三十二:把数组排成最小的数
三十五:数组中的逆序对
三十七:数字在排序数组中出现的次数
四十:数组中只出现一次的数字
五十:数组中重复的数字
五十一:构建乘积数组

字符串(8道):

二:替换空格
二十七:字符串的排列
三十四:第一个只出现一次的字符
四十三:左旋转字符串
四十四:翻转单词顺序序列
四十九:把字符串转换成整数
五十二:正则表达式匹配
五十三:表示数值的字符串

栈(3道):

五:用两个栈实现队列
二十:包含min函数的栈
二十一:栈的压入、弹出序列

递归(4道):

七:裴波那契数列
八:跳台阶
九:变态跳台阶
十:矩形覆盖

回溯法(2道):

六十五:矩阵中的路径
六十六:机器人的运动范围

其他(15道):

十一:二进制中1的个数
十二:数值的整数次方
十九:顺时针打印矩阵
二十九:最小的K个数
三十一:整数中1出现的次数(从1-n)
三十三:丑数
四十一:和为S的连续正数序列
四十二:和为S的两个数字
四十五:扑克牌顺子
四十六:孩子们的游戏(圆圈中最后剩下的数)
四十七:求1+2+3+…+n
四十八:不用加减乘除的加法
五十四:字符流中第一个不重复的字符
六十三:数据流中的中位数
六十四:滑动窗口的最大值

1.二维数组中的查找

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

class Solution:
    # array 二维列表
    def Find(self, target, array):
        
        for line in array:
            if target in line:
                return True
        return False

if __name__=='__main__':
    target=2
    array=[[1,2,3,4],[2,3,4,5],[3,4,5,6],[4,5,6,7]]
    solution=Solution()
    ans=solution.Find(target,array)
    print(ans)

2.替换空格
题目: 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
思路:利用字符串中的replace直接替换即可。

class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        
        temp = s.replace(" ", "%20")
        return temp

if __name__=='__main__':
    s='We Are Happy'
    solution=Solution()
    ans=solution.replaceSpace(s)
    print(ans)

3.从尾到头打印链表
题目:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
思路:将链表中的值记录到list之中,然后进行翻转list。

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

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        
        l=[]
        while listNode:
            l.append(listNode.val)
            listNode=listNode.next
        return l[::-1]

if __name__=='__main__':
    A1 = ListNode(1)
    A2 = ListNode(2)
    A3 = ListNode(3)
    A4 = ListNode(4)
    A5 = ListNode(5)

    A1.next=A2
    A2.next=A3
    A3.next=A4
    A4.next=A5

    solution=Solution()
    ans=solution.printListFromTailToHead(A1)
    print(ans)

4.重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
题解:首先前序遍历的第一个元素为二叉树的根结点,那么便能够在中序遍历之中找到根节点,那么在根结点左侧则是左子树,假设长度为M.在根结点右侧,便是右子树,假设长度为N。然后在前序遍历根节点后面M长度的便是左子树的前序遍历序列,再后面的N个长度便是右子树的后序遍历的长度。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        
        if len(pre)==0:
            return None
        if len(pre)==1:
            return TreeNode(pre[0])
        else:
            flag=TreeNode(pre[0])
            flag.left=self.reConstructBinaryTree(pre[1:tin.index(pre[0])+1],tin[:tin.index(pre[0])])
            flag.right=self.reConstructBinaryTree(pre[tin.index(pre[0])+1:],tin[tin.index(pre[0])+1:])
        return flag

if __name__=='__main__':
    solution=Solution()
    pre=list(map(int,input().split(',')))
    tin=list(map(int,input().split(',')))
    ans=solution.reConstructBinaryTree(pre,tin)
    print(ans.val)

5.用两个栈实现队列
题目:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
题解:申请两个栈Stack1和Stack2,Stack1当作输入,Stack2当作pop。当Stack2空的时候,将Stack1进行反转,并且输入到Stack2。

class Solution:
    def __init__(self):
        self.Stack1=[]
        self.Stack2=[]
    def push(self, node):
        self.Stack1.append(node)
    def pop(self):
        if self.Stack2==[]:
            while self.Stack1:
                self.Stack2.append(self.Stack1.pop())
            return self.Stack2.pop()
        return self.Stack2.pop()

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

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        
        minnum=999999
        for i in range(0,len(rotateArray)):
            if minnum>rotateArray[i]:
                minnum=rotateArray[i]
        if minnum:
            return minnum
        else:
            return 0

if __name__=='__main__':
    solution=Solution()
    rotateArray=list(map(int,input().split(',')))
    ans=solution.minNumberInRotateArray(rotateArray)
    print(ans)

7.斐波那契数列
题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39。
题解:递归和非递归方法。

class Solution:
    def Fibonacci(self, n):
        
        if n==0:
            return 0
        if n==1:
            return 1
        Fib=[0 for i in range(0,n+1)]
        Fib[0],Fib[1]=0,1
        for i in range(2,n+1):
            Fib[i]=Fib[i-1]+Fib[i-2]
        return Fib[n]
    def Fibonacci1(self,n):
        if n==0:
            return 0
        if n==1 or n==2:
            return 1
        else:
            return self.Fibonacci1(n-1)+self.Fibonacci1(n-2)

if __name__=='__main__':
    solution=Solution()
    n=int(input())
    ans=solution.Fibonacci1(n)
    print(ans)

8.跳台阶
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
题解:ans[n]=ans[n-1]+ans[n-2]

class Solution:
    def jumpFloor(self, number):
        
        if number==0:
            return 0
        if number==1:
            return 1
        if number==2:
            return 2
        ans=[0 for i in range(0,number+1)]
        ans[1],ans[2]=1,2
        for i in range(3,number+1):
            ans[i]=ans[i-1]+ans[i-2]
        return ans[number]


if __name__ == '__main__':
    solution = Solution()
    n=int(input())
    ans=solution.jumpFloor(n)
    print(ans)

9.变态跳台阶
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
题解:ans[n]=ans[n-1]+ans[n-2]+ans[n-3]+…+ans[n-n],ans[n-1]=ans[n-2]+ans[n-3]+…+ans[n-n],ans[n]=2*ans[n-1]。

class Solution:
    def jumpFloorII(self, number):
        
        if number==1:
            return 1
        if number==2:
            return 2
        return 2*self.jumpFloorII(number-1)

if __name__=='__main__':
    solution=Solution()
    n=int(input())
    ans=solution.jumpFloorII(n)
    print(ans)

10.矩形覆盖
题目:我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
题解:新增加的小矩阵竖着放,则方法与n-1时相同,新增加的小矩阵横着放,则方法与n-2时相同,于是f(n)=f(n-1)+f(n-2)。

class Solution:
    def rectCover(self, number):
        
        if number==0:
            return 0
        if number==1: 
            return 1
        Fib=[0 for i in range(0,number+1)]
        Fib[1],Fib[2]=1,2
        for i in range(3,number+1):
            Fib[i]=Fib[i-1]+Fib[i-2]
        return Fib[number]

if __name__=='__main__':
    solution=Solution()
    n=int(input())
    ans=solution.rectCover(n)
    print(ans)

11.二进制中1的个数
题目:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
题解:每次进行左移一位,然后与1进行相与,如果是1则进行加1。

class Solution:
    def NumberOf1(self, n):
        count = 0
        for i in range(32):
            count += (n >> i) & 1
        return count

if __name__=='__main__':
    solution=Solution()
    n=int(input())
    ans=solution.NumberOf1(n)
    print(ans)

12.数值的整次方
题目:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

class Solution:
    def Power(self, base, exponent):
        
        ans=1
        for i in range(0,abs(exponent)):
            ans=ans*base
        if exponent>0:
            return ans
        else:
            return 1/ans

if __name__=='__main__':
    solution=Solution()
    base=float(input())
    exponent=int(input())
    ans=solution.Power(base,exponent)
    print(ans)

13.调整数组顺序使奇数位于偶数前面
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
题解:申请奇数数组和偶数数组,分别存放奇数值和偶数值,数组相加便为结果。

class Solution:
    def reOrderArray(self, array):
        
        array1=[]#奇数
        array2=[]#偶数

        for i in range(0,len(array)):
            if array[i]%2!=0:
                array1.append(array[i])
            else:
                array2.append(array[i])
        ans=array1+array2
        return ans

if __name__=='__main__':
    solution=Solution()
    array=list(map(int,input().split(',')))
    ans=solution.reOrderArray(array)
    print(ans)

14.链表中倒数第K个节点
题目:输入一个链表,输出该链表中倒数第k个结点。
题解:反转链表,寻找第K个节点。

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

class Solution:
    def FindKthToTail(self, head, k):
        
        #反转链表
        if head is None or head.next is None:
            return head
        pre=None #指向上一个节点
        while head:
            #先用temp保存当前节点的下一个节点信息
            temp=head.next
            #保存好next之后,便可以指向上一个节点
            head.next=pre
            #让pre,head指向下一个移动的节点
            pre=head
            head=temp
        # 寻找第K个元素的位置
        for i in range(1,k):
            pre=pre.next
        temp=pre
        return temp

if __name__=='__main__':
    solution=Solution()
    k=3
    p1=ListNode(1)
    p2=ListNode(2)
    p3=ListNode(3)
    p4=ListNode(4)
    p1.next=p2
    p2.next=p3
    p3.next=p4

    ans=solution.FindKthToTail(p1,k)
    print(ans.val)

15.反转链表
题目:输入一个链表,反转链表后,输出新链表的表头。

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
        while pHead:
            #暂存当前节点的下一个节点信息
            temp=pHead.next
            #反转节点
            pHead.next=pre
            #进行下一个节点
            pre = pHead
            pHead=temp
        return pre

if __name__=='__main__':
    solution=Solution()
    p1=ListNode(1)
    p2=ListNode(2)
    p3=ListNode(3)
    p1.next=p2
    p2.next=p3
    ans=solution.ReverseList(p1)
    print(ans.val)

16.合并两个排序的列表
题目:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
题解:将两个链表之中的数值转换到列表之中,并进行排序,将排序后的列表构造成链表。

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

class Solution:
    # 返回合并后列表
    def Merge(self,pHead1,pHead2):
        
        if pHead1 is None and pHead2 is None:
            return None
        num1,num2=[],[]
        while pHead1:
            num1.append(pHead1.val)
            pHead1=pHead1.next
        while pHead2:
            num2.append(pHead2.val)
            pHead2=pHead2.next
        ans=num1+num2
        ans.sort()
        head=ListNode(ans[0])
        pre=head
        for i in range(1,len(ans)):
            node=ListNode(ans[i])
            pre.next=node
            pre=pre.next
        return head

if __name__=='__main__':
    solution=Solution()
    pHead1_1 = ListNode(1)
    pHead1_2 = ListNode(3)
    pHead1_3 = ListNode(5)
    pHead1_1.next=pHead1_2
    pHead1_2.next=pHead1_3

    pHead2_1 = ListNode(2)
    pHead2_2 = ListNode(4)
    pHead2_3 = ListNode(6)
    pHead2_1.next=pHead2_2
    pHead2_2.next=pHead2_3
    ans=solution.Merge(pHead1_1,pHead2_1)
    print(ans)

17.树的子结构
题目:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)。
题解:将树转变为中序序列,然后转变为str类型,最后判断是否包含。

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
        pRoot1_result,pRoot2_result=[],[]
        self.order_traversal(pRoot1,pRoot1_result)
        self.order_traversal(pRoot2,pRoot2_result)
        str1=''.join(str(i) for i in pRoot1_result)
        str2=''.join(str(i) for i in pRoot2_result)
        print(str1,str2)
        if str2 in str1:
            return True
        else:
            return False
    def order_traversal(self,root,result):
        if not root:
            return
        self.order_traversal(root.left,result)
        result.append(root.val)
        self.order_traversal(root.right,result)

18.二叉树的镜像
题目: 操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
8 镜像二叉树8
/ \ /
6 10 10 6
/ \ / \ / \ /
5 7 9 11 11 9 7 5
思路:递归实现反转每个子节点

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        
        # A1_order_result=[]
        # self.order_traversal(A1,A1_order_result)
        if root is None:
            return
        if root.left is None and root.right is None:
            return
        temp=root.left
        root.left=root.right
        root.right=temp

        if root is not None:
            self.Mirror(root.left)
        if root is not None:
            self.Mirror(root.right)

    def order_traversal(self,root,result):
        if not root:
            return
        self.order_traversal(root.left,result)
        result.append(root.val)
        self.order_traversal(root.right,result)

if __name__=='__main__':
    A1 = TreeNode(8)
    A2 = TreeNode(6)
    A3 = TreeNode(10)
    A4 = TreeNode(5)
    A5 = TreeNode(7)
    A6 = TreeNode(9)
    A7 = TreeNode(11)
    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    A3.left=A6
    A3.right=A7

    temp1=[]
    solution=Solution()
    solution.order_traversal(A1,temp1)
    print(temp1)
    solution.Mirror(A1)
    solution.order_traversal(A1,temp1)
    print(temp1)

19.顺时针打印矩阵
题目:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
例如,如果输入如下矩阵:
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):
        
        m,n=len(matrix),len(matrix[0])
        res = []
        if n==1 and m==1:
            res.append(matrix[0][0])
            return res
        for k in range(0,(min(m,n)+1)//2):
            [res.append(matrix[k][i]) for i in range(k, n - k)]
            [res.append(matrix[j][n-k-1]) for j in range(k,m-k) if matrix[j][n-k-1] not in res]
            [res.append(matrix[m-k-1][j]) for j in range(n-k-1,k-1,-1) if matrix[m-k-1][j] not in res]
            [res.append(matrix[j][k]) for j in range(m-1-k,k-1,-1) if matrix[j][k] not in res]
        return res

if __name__=='__main__':
    solution=Solution()
    m,n=1,5
    matrix=[]
    for i in range(0,m):
        matrix.append(list(map(int,input().split(' '))))
    print(matrix)
    ans=solution.printMatrix(matrix)
    print(ans)

20.包含Min函数的栈
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数。

class Solution:
    def __init__(self):
        self.num=[]
    def push(self, node):
        
        self.num.append(node)
    def pop(self):
        
        self.num.pop()
    def top(self):
        
        numlen = len(self.num)
        return self.num[numlen-1]
    def min(self):
        
        return min(self.num)

if __name__=='__main__':
    solution = Solution()
    solution.push(1)
    solution.push(2)
    solution.push(3)
    solution.push(4)
    solution.pop()
    print(solution.top())
    print(solution.min())          

21.栈的压入弹出序列
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)。
题解:新构建一个中间栈,来模拟栈的输入和栈的输出,比对输入结果和输出结果是否相等。

class Solution:
    def IsPopOrder(self, pushV, popV):
        
        if len(pushV)==1 and len(popV)==1 and pushV[0]!=popV[0]:
            return False

        helpV=[]
        pushV.reverse()
        popV.reverse()
        #模拟给定栈的压入和压出
        helpV.append(pushV[len(pushV)-1])
        pushV.pop()
        while True:
            if helpV[len(helpV)-1]!=popV[len(popV)-1]:
                helpV.append(pushV[len(pushV)-1])
                pushV.pop()

            if helpV[len(helpV)-1]==popV[len(popV)-1]:
                helpV.pop()
                popV.pop()

            if pushV==[] and popV==[] and helpV==[]:
                return True

            if pushV==[] and popV[len(popV)-1]!=helpV[len(helpV)-1]:
                return False


if __name__=='__main__':
    solution=Solution()
    push=list(map(int,input().split(' ')))
    pop=list(map(int,input().split(' ')))
    ans=solution.IsPopOrder(push,pop)
    print(ans)

22.从上往下打印二叉树
题目:从上往下打印出二叉树的每个节点,同层节点从左至右打印。
思路:递归,每次将左子树结果和右子树结果存到结果集之中。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    # 返回从上到下每个节点值列表,例:[1,2,3]
    def PrintFromTopToBottom(self, root):
        
        if root is None:
            return []
        ans=[]
        ans.append(root.val)
        self.orderans(root,ans)
        return ans

    def orderans(self,root,ans):
        if not root:
            return
        if root.left:
            ans.append(root.left.val)
        if root.right:
            ans.append(root.right.val)

        self.orderans(root.left, ans)
        self.orderans(root.right,ans)

if __name__=='__main__':
    solution=Solution()
    A1 = TreeNode(1)
    A2 = TreeNode(2)
    A3 = TreeNode(3)
    A4 = TreeNode(4)
    A5 = TreeNode(5)

    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    ans=solution.PrintFromTopToBottom(A1)
    print(ans)

23.二叉树的后续遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
思路:二叉搜索树的特性是所有左子树值都小于中节点,所有右子树的值都大于中节点,递归遍历左子树和右子树的值。

class Solution:
    def VerifySquenceOfBST(self, sequence):
        if not sequence:
            return False
        if len(sequence)==1:
            return True
        i=0
        while sequence[i]<sequence[-1]:
            i=i+1
        k=i
        for j in range(i,len(sequence)-1):
            if sequence[j]<sequence[-1]:
                return False
        leftsequence=sequence[:k]
        rightsequence=sequence[k:len(sequence)-1]
        leftans=True
        rightans=True
        if len(leftsequence)>0:
            self.VerifySquenceOfBST(leftsequence)
        if len(rightsequence)>0:
            self.VerifySquenceOfBST(rightsequence)
        return leftans and rightans

if __name__=='__main__':
    solution=Solution()
    num=list(map(int,input().split(' ')))
    ans=solution.VerifySquenceOfBST(num)
    print(ans)

24.二叉树中和为某一值的路径
题目:输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)。
思路:利用递归的方法,计算加左子树和右子树之后的值,当参数较多是,可以将结果添加到函数变量之中。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    # 返回二维列表,内部每个列表表示找到的路径
    def FindPath(self, root, expectNumber):
        
        if not root:
            return []
        ans=[]
        path=[]
        self.dfs(root,expectNumber,ans,path)
        ans.sort()
        return ans

    def dfs(self,root,target,ans,path):
        if not root:
            return

        path.append(root.val)
        if root.left is None and root.right is None and target==root.val:
            ans.append(path[:])

        if root.left:
            self.dfs(root.left,target-root.val,ans,path)
        if root.right:
            self.dfs(root.right,target-root.val,ans,path)

        path.pop()


if __name__=='__main__':
    A1=TreeNode(10)
    A2=TreeNode(8)
    A3=TreeNode(12)
    A4=TreeNode(4)
    A5=TreeNode(2)
    A6=TreeNode(2)

    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    A5.left=A6

    expectNumber=22
    solution=Solution()
    ans=solution.FindPath(A1,expectNumber)
    print(ans)

25.复杂链表的复制
题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。
思路:将大问题转变为小问题,每次都进行复制头部节点,然后进行递归,每次同样处理头部节点。

class Solution:
    # 返回 RandomListNode
    def Clone(self, pHead):
        if not pHead:
            return None
        #创建新链表
        pCur=pHead
        while pCur:
            pCur_next=pCur.next
            newnode=RandomListNode(pCur.label)
            newnode.next=pCur_next
            pCur.next=newnode
            pCur=pCur_next
        #改变新链表的random指针
        pCur=pHead
        while pCur:
            pCur_random=pCur.random
            newnode=pCur.next
            if pCur_random:
                newnode.random=pCur_random.next
            pCur=newnode.next
        pCur=pHead
        result=pHead.next
        #分离两链表
        while pCur:
            newnode=pCur.next
            pCur_next=newnode.next
            pCur.next=pCur_next
            if pCur_next:
                newnode.next=pCur_next.next
            else:
                newnode.next=None
            pCur=pCur.next
        return result

26.二叉搜索树与双向列表
题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路:递归将根结点和左子树的最右节点和右子树的最左节点进行连接起来。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def Convert(self, pRootOfTree):
        
        if pRootOfTree is None:
            return pRootOfTree
        if pRootOfTree.left is None and pRootOfTree.right is None:
            return pRootOfTree
        #处理左子树
        self.Convert(pRootOfTree.left)
        left=pRootOfTree.left
        if left:
            while left.right:
                left=left.right
            pRootOfTree.left,left.right=left,pRootOfTree
        #处理右子树
        self.Convert(pRootOfTree.right)
        right=pRootOfTree.right
        if right:
            while right.left:
                right=right.left
           RootOfTree.right,right.left=right,pRootOfTree
        while pRootOfTree.left:
            pRootOfTree=pRootOfTree.left
        return pRootOfTree

27.字符串的排列
题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入:输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
思路:通过将第k位的字符提取到最前面,然后进行和后面的每个字符进行交换,得到所有结果集。

class Solution:
    def Permutation(self, ss):
        
        if not ss:
            return []
        res=[]
        self.helper(ss,res,'')
        return sorted(list(set(res)))

    def helper(self,ss,res,path):
        if not ss:
            res.append(path)
        else:
            for i in range(0,len(ss)):
                self.helper(ss[:i]+ss[i+1:],res,path+ss[i])

if __name__=='__main__':
    str='abbcDeefg'
    str1='abbc'
    solution=Solution()
    ans=solution.Permutation(str1)
    print(ans)

28.数组中出现次数超过一般的数字
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0
题解:利用list列表来存放每个数出现的次数ans[numbers[i]]=ans[numbers[i]]+1。

class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        
        numlen=len(numbers)
        halflen=numlen//2
        maxans=0
        ans=[0 for i in range(0,1000)]
        for i in range(0,len(numbers)):
            ans[numbers[i]]=ans[numbers[i]]+1
            if ans[numbers[i]]>maxans:
                maxans=numbers[i]
        ans.sort()
        ans.reverse()
        res=ans[0]
        if res>halflen:
            return maxans
        else:
            return 0
if __name__=='__main__':
    num=list(map(int,input().split(',')))
    solution=Solution()
    ans=solution.MoreThanHalfNum_Solution(num)
    print(ans)

29.最小的K个数
题目:输入n个整数,找出其中最小的K个数,例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。

class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        
        if k>len(tinput):
            return []
        tinput.sort()
        return tinput[:k]

if __name__=='__main__':
    num=list(map(int,input().split(',')))
    k=int(input())
    solution=Solution()
    ans=solution.GetLeastNumbers_Solution(num,k)
    print(ans)

30.连续子数组的最大和
题目:HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度至少是1)

class Solution:
    def FindGreatestSumOfSubArray(self, array):
        
        maxsum,tempsum=array[0],array[0]
        for i in range(1,len(array)):
            if tempsum<0:
                tempsum=array[i]
            else:
                tempsum = tempsum + array[i]
            if tempsum>maxsum:
                maxsum=tempsum
        return maxsum

if __name__=='__main__':
    array=list(map(int,input().split(',')))
    solution=Solution()
    ans=solution.FindGreatestSumOfSubArray(array)
    print(ans)

31.整数中1出现的次数
题目:求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
思路:对每个数字的每位进行分解,含有1则结果加1。

class Solution:
    def NumberOf1Between1AndN_Solution(self, n):
        
        ans=0
        for i in range(1,n+1):
            tempans=0
            while i!=0:
                eachnum=i%10
                i=i//10
                if eachnum==1:
                    tempans=tempans+1
            ans=ans+tempans
        return ans

if __name__=='__main__':
    n=130
    solution=Solution()
    ans=solution.NumberOf1Between1AndN_Solution(n)
    print(ans)

32.把数组排成最小的数
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路:将数组转换成字符串之后,进行两两比较字符串的大小,比如3,32的大小由332和323确定,即3+32和32+3确定。

class Solution:
    def PrintMinNumber(self, numbers):
        
        if not numbers:
            return ""
        num = map(str, numbers)
        for i in range(0,len(numbers)):
            for j in range(i,len(numbers)):
if int(str(numbers[i])+str(numbers[j])) >int(str(numbers[j])+
str(numbers[i])):
        numbers[i],numbers[j]=numbers[j],numbers[i]
        ans=''
        for i in range(0,len(numbers)):
            ans=ans+str(numbers[i])
        return ans

if __name__=='__main__':
    numbers=[3,32,321]
    solution=Solution()
    ans=solution.PrintMinNumber(numbers)
    print(ans)

33.丑数
题目:把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路:每一个丑数必然是由之前的某个丑数与2,3或5的乘积得到的,这样下一个丑数就用之前的丑数分别乘以2,3,5,找出这三这种最小的并且大于当前最大丑数的值,即为下一个要求的丑数。

class Solution:
    def GetUglyNumber_Solution(self, index):
        
        if (index <= 0):
            return 0
        uglyList = [1]
        indexTwo = 0
        indexThree = 0
        indexFive = 0
        for i in range(index-1):
            newUgly = min(uglyList[indexTwo]*2, uglyList[indexThree]*3, uglyList[indexFive]*5)
            uglyList.append(newUgly)
            if (newUgly % 2 == 0):
                indexTwo += 1
            if (newUgly % 3 == 0):
                indexThree += 1
            if (newUgly % 5 == 0):
                indexFive += 1
        return uglyList[-1]

if __name__=='__main__':
    solution=Solution()
    index=200
    ans=solution.GetUglyNumber_Solution(index)
    print(ans)

34.第一个只出现一次的字符
题目:在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1。
思路:找出所有出现一次的字符,然后进行遍历找到第一次出现字符的位置。

class Solution:
    def FirstNotRepeatingChar(self, s):
        
        if not s:
            return -1
        sset=set(s)
        dict={}
        for c in sset:
            dict[c]=0
        for i in range(0,len(s)):
            dict[s[i]]=dict[s[i]]+1
        onetime=[]
        for c in dict:
            if dict[c]==1:
                onetime.append(c)

        if onetime is None:
            return -1
        else:
            index=0
            for i in range(0,len(s)):
                if s[i] in onetime:
                    index=i
                    break
            return index

if __name__=='__main__':
    s='abbddebbac'
    solution=Solution()
    ans=solution.FirstNotRepeatingChar(s)
    print(ans)

35.数组中的逆序对
题目描述:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007。
输入描述:题目保证输入的数组中没有的相同的数字。
数据范围:对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100的数据,size<=2*10^5
示例1
输入 1,2,3,4,5,6,7,0
输出 7

class Solution:
    def InversePairs(self, data):
        
        global count
        count = 0

        def A(array):
            global count
            if len(array) <= 1:
                return array
            k = int(len(array) / 2)
            left = A(array[:k])
            right = A(array[k:])
            l = 0
            r = 0
            result = []
            while l < len(left) and r < len(right):
                if left[l] < right[r]:
                    result.append(left[l])
                    l += 1
                else:
                    result.append(right[r])
                    r += 1
                    count += len(left) - l
            result += left[l:]
            result += right[r:]
            return result

        A(data)
        return count % 1000000007

if __name__=='__main__':
    data=[1,2,3,4,5,6,7,0]
    solution=Solution()
    ans=solution.InversePairs(data)
    print(ans)

36.两个链表的第一个公共节点
题目:输入两个链表,找出它们的第一个公共结点。

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        
        list1 = []
        list2 = []
        node1 = pHead1
        node2 = pHead2
        while node1:
            list1.append(node1.val)
            node1 = node1.next
        while node2:
            if node2.val in list1:
                return node2
            else:
                node2 = node2.next

if __name__=='__main__':
    A1 = ListNode(1)
    A2 = ListNode(2)
    A3 = ListNode(3)
    A1.next=A2
    A2.next=A3

    B4 = ListNode(4)
    B5 = ListNode(5)
    B4.next=B5

    C6=ListNode(6)
    C7=ListNode(7)

    A3.next=C6
    B5.next=C6
    C6.next=C7

    solution=Solution()
    ans=solution.FindFirstCommonNode(A1,B4)
    print(ans.val)

37.数字在排序数组中出现的次数
题目:统计一个数字在排序数组中出现的次数。

class Solution:
    def GetNumberOfK(self, data, k):
        
        ans=0
        for i in range(0,len(data)):
            if data[i]==k:
                ans=ans+1
            if data[i]>k:
                break
        return ans

if __name__=='__main__':
    data=[1,2,3,3,3,4,4,5]
    k=3
    solution=Solution()
    ans=solution.GetNumberOfK(data,k)
    print(ans)

38.二叉树的深度
题目:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def TreeDepth(self, pRoot):
        
        if pRoot is None:
            return 0
        left=self.TreeDepth(pRoot.left)
        right=self.TreeDepth(pRoot.right)
        print(left,right)
        return max(left,right)+1

if __name__=='__main__':
    A1 = TreeNode(1)
    A2 = TreeNode(2)
    A3 = TreeNode(3)
    A4 = TreeNode(4)
    A5 = TreeNode(5)
    A6 = TreeNode(6)

    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    A4.left=A6

    solution=Solution()
    ans=solution.TreeDepth(A1)
    print('ans=',ans)

39.平衡二叉树
题目:输入一棵二叉树,判断该二叉树是否是平衡二叉树。
题解:平衡二叉树是左右子数的距离不能大于1,因此递归左右子树,判断子树距离是否大于1。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def IsBalanced_Solution(self, pRoot):
        
        if pRoot is None:
            return True
        if abs(self.TreeDepth(pRoot.left)-self.TreeDepth(pRoot.right))>1:
            return False
        return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)

    def TreeDepth(self,root):
        if root is None:
            return 0
        left=self.TreeDepth(root.left)
        right=self.TreeDepth(root.right)
        return max(left+1,right+1)

if __name__=='__main__':
    A1 = TreeNode(1)
    A2 = TreeNode(2)
    A3 = TreeNode(3)
    A4 = TreeNode(4)
    A5 = TreeNode(5)
    A6 = TreeNode(6)

    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    #A4.left=A6

    solution=Solution()
    ans=solution.IsBalanced_Solution(A1)
    print(ans)

40.数组中只出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。
题解:将数组中数转到set之中,然后利用dict存储每个数字出现的次数。

class Solution:
    # 返回[a,b] 其中ab是出现一次的两个数字
    def FindNumsAppearOnce(self, array):
        
        arrayset=set(array)
        dict={}
        for num in arrayset:
            dict[num]=0
        for i in range(0,len(array)):
            dict[array[i]]=dict[array[i]]+1
        ans=[]
        for num in arrayset:
            if dict[num]==1:
                ans.append(num)
        return ans


if __name__=='__main__':
    array=[1,1,2,2,3,3,4,5,5,6,7,7]
    solution=Solution()
    ans=solution.FindNumsAppearOnce(array)
    print(ans)

41.和为S的连续正整数序列
题目:小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述:输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序。
思路:首项加尾项*2等于和,那么只要遍历项的开始和长度即可。

class Solution:
    def FindContinuousSequence(self, tsum):
        
        ans=[]
        for i in range(1,tsum//2+1):
            oneans=[]
            for k in range(1,tsum):
                tempsum=((i+i+k-1)*k)//2
                if tempsum==tsum:
                    for j in range(i,i+k):
                        oneans.append(j)
                    break
            if oneans !=[]:
                ans.append(oneans)
        return ans

if __name__=='__main__':
    tsum=15
    solution=Solution()
    ans=solution.FindContinuousSequence(tsum)
    print(ans)

42.和为S的两个数字
题目:输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输出描述:对应每个测试案例,输出两个数,小的先输出。
思路:利用i和j从后面进行扫描结果,选取最小的乘积放入到结果集之中。

class Solution:
    def FindNumbersWithSum(self, array, tsum):
        
        ans=[]
        i,j,minres=0,len(array)-1,1000000
        for i in range(0,len(array)-1):
            j=len(array)-1
            while True:
                tempsum = array[i] + array[j]
                if tempsum == tsum:
                    if array[i]*array[j]<minres:
                        ans=[]
                        ans.append(array[i])
                        ans.append(array[j])
                        minres=array[i]*array[j]
                    break
                else:
                    j = j - 1
                if tempsum<tsum:
                    break
                if j<=i:
                    break
        return ans

if __name__=='__main__':
    array=[1,2,4,7,11,15]
    tsum=15
    solution=Solution()
    ans=solution.FindNumbersWithSum(array,tsum)
    print(ans)

43.左旋字符子串
题目:汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

class Solution:
    def LeftRotateString(self, s, n):
        
        if s=='' and n==0:
            return ''
        ans=''
        ans=s[n:]+s[0:n]
        return ans

if __name__=='__main__':
    s='abcdefg'
    n=2
    solution=Solution()
    ans=solution.LeftRotateString(s,n)
    print(ans)

44.反转单词顺序
题目:牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

class Solution:
    def ReverseSentence(self, s):
        
        ans,word=[],''
        for i in range(0,len(s)):
            word = word + s[i]
            if s[i]==' ':
                ans.append(word)
                word=''
            if i==len(s)-1:
                word=word+' '
                ans.append(word)
        ans.reverse()
        res=''
        for c in ans:
            res=res+c
        return res[:len(res)-1]

if __name__=='__main__':
    solution=Solution()
    s='I am a student.'
    ans=solution.ReverseSentence(s)
    print(ans)

45.扑克牌顺序
题目:LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。

class Solution:
    def IsContinuous(self, numbers):
        
        if numbers==[]:
            return False
        numbers.sort()
        zero=0
        for i in range(0,len(numbers)):
            if numbers[i]==0:
                zero=zero+1
        for i in range(zero+1,len(numbers)):
            if numbers[i]==numbers[i-1]:
                return False
            if numbers[i]-numbers[i-1]==1:
                continue
            else:
                diff=numbers[i]-numbers[i-1]-1
                zero=zero-diff

        if zero<0:
            return False
        return True

if __name__=='__main__':
    numbers=[1,0,0,1,0]
    solution=Solution()
    ans=solution.IsContinuous(numbers)
    print(ans)

46.孩子们的圈圈(圈圈中最后剩下的数)
题目:每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)。
思路:约瑟夫环问题。
题目
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。
其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。
每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,
从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,
并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

思路
约瑟夫环问题

class Solution:
    def LastRemaining_Solution(self, n, m):
        
        if n<1 or m<1:
            return -1
        last=0
        for i in range(2,n+1):
            last=(last+m)%i
        return last

if __name__=='__main__':
    n,m=8,4
    solution=Solution()
    ans=solution.LastRemaining_Solution(n,m)
    print(ans)

47.求1+2+3+…+n
题目:求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
思路:利用递归当作计算结果。

class Solution:
    def Sum_Solution(self, n):
        
        if n==0:
            return 0
        return self.Sum_Solution(n-1)+n

if __name__=='__main__':
    n=6
    solution=Solution()
    ans=solution.Sum_Solution(n)
    print(ans)

48.不用加减乘除做加法
题目:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
思路:二进制异或进位。

class Solution:
    def Add(self, num1, num2):
        
        while num2!=0:
            sum=num1^num2
            carry=(num1&num2)<<1
            num1=sum
            num2=carry
        return num1

if __name__=='__main__':
    num1,num2=10,500000
    solution=Solution()
    ans=solution.Add(num1,num2)
    print(ans)

49.把字符串转换成整数
题目:将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
输入描述:输入一个字符串,包括数字字母符号,可以为空输出描述:如果是合法的数值表达则返回该数字,否则返回0。
示例
+2147483647
1a33
2147483647
0

class Solution:
    def StrToInt(self, s):
        
        if len(s) == 0:
            return 0
        else:
            if s[0] > '9' or s[0] < '0':
                a = 0
            else:
                a = int(s[0]) * 10 ** (len(s) - 1)
            if len(s) > 1:
                for i in range(1, len(s)):
                    if s[i] >= '0' and s[i] <= '9':
                        a = a + int(s[i]) * 10 ** (len(s) - 1 - i)
                    else:
                        return 0
        if s[0] == '+':
            return a
        if s[0] == '-':
            return -a
        return a

if __name__=='__main__':
    s='115'
    solution=Solution()
    ans=solution.StrToInt(s)
    print(ans)

50.数组中重复的数字
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思路:利用dict计算重复数字。

class Solution:
    # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    # 函数返回True/False
    def duplicate(self, numbers, duplication):
        
        numset=set(numbers)
        dict={}
        duplication.append(0)
        for val in numbers:
            dict[val]=0
        for i in range(0,len(numbers)):
            dict[numbers[i]]=dict[numbers[i]]+1
        for val in numset:
            if dict[val]>1:
                duplication[0]=val
                return True
        return False

if __name__=='__main__':
    numbers=[2,1,3,1,4]
    solution=Solution()
    duplication=[]
    ans=solution.duplicate(numbers,duplication)
    print(ans)

51.构建乘积数组
#题目
#给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],
其中B中的元素B[i]=A[0]A[1]A[i-1]A[i+1]A[n-1]。不能使用除法。
思路审题仔细 没有A[i]
52.正则表达式匹配
题目:请实现一个函数用来匹配包括’.‘和’
‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’
'表示它前面的字符可以出现任意次(包含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"aba"均不匹配。
思路:
当模式中的第二个字符不是 时:
如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的。
如果字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。
当模式中的第二个字符是 时:
如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。
如果字符串第一个字符跟模式第一个字符匹配,可以有3种匹配方式。
模式后移2字符,相当于 x
被忽略。即模式串中
与他前面的字符和字符串匹配0次。
字符串后移1字符,模式后移2字符。即模式串中
与他前面的字符和字符串匹配1次。
字符串后移1字符,模式不变,即继续匹配字符下一位,因为 可以匹配多位。即模式串中与他前面的字符和字符串匹配多次。

class Solution:
    # s, pattern都是字符串
    def match(self, s, pattern):
        if s == pattern:
            return True
        if not pattern:
            return False
        if len(pattern) > 1 and pattern[1] == '*':
            if (s and s[0] == pattern[0]) or (s and pattern[0] == '.'):
                return self.match(s, pattern[2:]) \
                       or self.match(s[1:], pattern) \
                       or self.match(s[1:], pattern[2:])
            else:
                return self.match(s, pattern[2:])
        elif s and (s[0] == pattern[0] or pattern[0] == '.'):
            return self.match(s[1:], pattern[1:])
        return False

if __name__=='__main__':
    solution=Solution()
    s='aaa'
    pattern='a*a.a'
    ans=solution.match(s,pattern)
    print(ans)

53.表示数值的字符串
题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。

class Solution:
    # s字符串
    def isNumeric(self, s):
        
        # 标记符号、小数点、e是否出现过
        sign,decimal,hasE=False,False,False
        for i in range(0,len(s)):
            if s[i]=='e' or s[i]=='E':
                if i==len(s)-1:# e后面一定要接数字
                    return False
                if hasE==True:# 不能出现两次e
                    return False
                hasE=True
            elif s[i]=='+' or s[i]=='-':
                #第二次出现+或-一定要在e之后
                if sign and s[i-1]!='e' and s[i-1]!='E':
                    return False
                # 第一次出现+或-,如果不是出现在字符最前面,那么就要出现在e或者E后面
                if sign==False and i>0 and s[i-1]!='e' and s[i-1]!='E':
                    return False
                sign=True
            elif s[i]=='.':
                # e后面不能出现小数点,小数点不能出现两次
                if decimal or hasE:
                    return False
                decimal=True
            elif s[i]>'9' or s[i]<'0':
                return False
        return True

if __name__=='__main__':
    solution=Solution()
    s='123e.1416'
    ans=solution.isNumeric(s)
    print(ans)

54.字符流中第一个不重复的字符
题目:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:如果当前字符流没有存在出现一次的字符,返回#字符。

class Solution:
    # 返回对应char
    def __init__(self):
        self.all={}
        self.ch=[]
    def FirstAppearingOnce(self):
        
        if self.all is None:
            return '#'
        for c in self.ch:
            if self.all[c]==1:
                return c
        return '#'

    def Insert(self, char):
        
        self.ch.append(char)
        if char in self.all:
            self.all[char]=self.all[char]+1
        else:
            self.all[char]=1

if __name__=='__main__':
    solution=Solution()
    solution.Insert('g')
    ans = solution.FirstAppearingOnce()
    print(ans)
    solution.Insert('o')
    ans = solution.FirstAppearingOnce()
    print(ans)
    solution.Insert('o')
    ans = solution.FirstAppearingOnce()
    print(ans)
    solution.Insert('g')
    ans = solution.FirstAppearingOnce()
    print(ans)
    solution.Insert('l')
    ans = solution.FirstAppearingOnce()
    print(ans)
    solution.Insert('e')
    ans = solution.FirstAppearingOnce()
    print(ans)

55.链表中环的入口节点
题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路:把链表中节点值放到dict数组中,并记录出现的次数,如果出现次数超过一次,则为环的入口节点。

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        
        if pHead is None:
            return None
        num,dict,flag=[],{},True
        tempans=0
        while pHead and flag==True:
            num.append(pHead.val)
            numset=set(num)
            for c in numset:
                dict[c]=0
            for c in num:
                dict[c]=dict[c]+1
            for c in num:
                if dict[c]>1:
                    flag=False
                    tempans=c
            pHead=pHead.next
        while pHead:
            if pHead.val==tempans:
                return pHead
            pHead=pHead.next
        return None

if __name__=='__main__':
    pHead1 = ListNode(1)
    pHead2 = ListNode(2)
    pHead3 = ListNode(3)
    pHead4 = ListNode(4)
    pHead5 = ListNode(5)

    pHead1.next=pHead2
    pHead2.next=pHead3
    pHead3.next=pHead4
    pHead4.next=pHead5
    pHead5.next=pHead1

    solution=Solution()
    ans=solution.EntryNodeOfLoop(pHead1)
    print(ans.val)

56.删除链表中重复的节点
题目:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。
思路:记录链表中出现的数字,然后构建新链表。

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        
        num=[]
        tempnum1=pHead
        while tempnum1:
            num.append(tempnum1.val)
            tempnum1=tempnum1.next
        dict={}
        for c in num:
            dict[c]=0
        for c in num:
            dict[c]=dict[c]+1
        newnum=[]
        for c in num:
            if dict[c]==1:
                newnum.append(c)
        if newnum==[]:
            return None
        head=ListNode(newnum[0])
        temphead=head
        for i in range(1,len(newnum)):
            tempnode=ListNode(newnum[i])
            temphead.next=tempnode
            temphead=tempnode
        # while head:
        #     print(head.val)
        #     head=head.next
        return head

if __name__=='__main__':
    pHead1 = ListNode(1)
    pHead2 = ListNode(1)
    pHead3 = ListNode(1)
    pHead4 = ListNode(1)
    pHead5 = ListNode(1)
    pHead6 = ListNode(1)
    pHead7 = ListNode(1)

    pHead1.next=pHead2
    pHead2.next=pHead3
    pHead3.next=pHead4
    pHead4.next=pHead5
    pHead5.next=pHead6
    pHead6.next=pHead7

    solution=Solution()
    ans=solution.deleteDuplication(pHead1)
    print(ans)
  1. 二叉树中的下一个节点
    题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
    思路:分析二叉树的下一个节点,一共有以下情况:1.二叉树为空,则返回空;2.节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点即为下一个节点;3.节点不是根节点。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,重复之前的判断,返回结果。
class TreeLinkNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
        self.next = None
class Solution:
    def GetNext(self, pNode):
        
        if not pNode:
            return pNode
        if pNode.right:
            left1=pNode.right
            while left1.left:
                   left1=left1.left
            return left1

        while pNode.next:
            tmp=pNode.next
            if tmp.left==pNode:
                return tmp
            pNode=tmp

if __name__=='__main__':
    solution=Solution()

58.对称的二叉树
题目:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
思路:采用递归的方法来判断两数是否相同。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def isSymmetrical(self, pRoot):
        
        if not pRoot:
            return True
        result=self.same(pRoot,pRoot)
        return result
    def same(self,root1,root2):
        if not root1 and not root2:
            return True
        if root1 and not root2:
            return False
        if not root1 and root2:
            return False
        if root1.val!= root2.val:
            return False

        left=self.same(root1.left,root2.right)
        if not left:
            return False
        right=self.same(root1.right,root2.left)
        if not right:
            return False
        return True

if __name__=='__main__':

    A1 = TreeNode(1)
    A2 = TreeNode(2)
    A3 = TreeNode(2)
    A4 = TreeNode(3)
    A5 = TreeNode(4)
    A6 = TreeNode(4)
    A7 = TreeNode(3)

    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    A3.left=A6
    A3.right=A7


    solution = Solution()
    ans=solution.isSymmetrical(A1)
    print(ans)

59.按之字形顺序打印二叉树
题目:请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路: 把当前列结果存放到list之中,设置翻转变量,依次从左到右打印和从右到左打印。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def Print(self, pRoot):
        
        root=pRoot
        if not root:
            return []
        level=[root]
        result=[]
        righttoleft=False
        while level:
            curvalues=[]
            nextlevel=[]
            for i in level:
                curvalues.append(i.val)
                if i.left:
                    nextlevel.append(i.left)
                if i.right:
                    nextlevel.append(i.right)
            if righttoleft:
                    curvalues.reverse()
            if curvalues:
                    result.append(curvalues)
            level = nextlevel
            righttoleft = not righttoleft
        return result

if __name__=='__main__':
    A1 = TreeNode(1)
    A2 = TreeNode(2)
    A3 = TreeNode(3)
    A4 = TreeNode(4)
    A5 = TreeNode(5)
    A6 = TreeNode(6)
    A7 = TreeNode(7)

    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    A3.left=A6
    A3.right=A7

    solution = Solution()
    ans=solution.Print(A1)
    print(ans)

60.把二叉树打印成多行
题目:从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    # 返回二维列表[[1,2],[4,5]]
    def Print(self, pRoot):
        
        root=pRoot
        if not root:
            return []
        level=[root]
        result=[]
        while level:
            curvalues=[]
            nextlevel=[]
            for i in level:
                curvalues.append(i.val)
                if i.left:
                    nextlevel.append(i.left)
                if i.right:
                    nextlevel.append(i.right)
            if curvalues:
                    result.append(curvalues)
            level = nextlevel
        return result

if __name__=='__main__':
    A1 = TreeNode(1)
    A2 = TreeNode(2)
    A3 = TreeNode(3)
    A4 = TreeNode(4)
    A5 = TreeNode(5)
    A6 = TreeNode(6)
    A7 = TreeNode(7)

    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    A3.left=A6
    A3.right=A7

    solution = Solution()
    ans=solution.Print(A1)
    print(ans)

61.序列化二叉树
题目:请实现两个函数,分别用来序列化和反序列化二叉树。
思路:转变成前序遍历,空元素利用"#"代替,然后进行解序列。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

import collections
class Solution:
    def Serialize(self, root):
        
        if not root:
            return None
        res=[]
        self.pre(root,res)
        return res

    def pre(self,root,res):
        if not root:
            return
        res.append(root.val)
        if root.left:
            self.pre(root.left, res)
        else:
            res.append('#')
        if root.right:
            self.pre(root.right,res)
        else:
            res.append('#')
    def Deserialize(self, s):
        if s=='':
            return None
        vals=[]
        for i in range(0,len(s)):
            vals.append(s[i])
        vals=collections.deque(vals)
        ans=self.build(vals)
        return ans

    def build(self,vals):
        if vals:
            val = vals.popleft()
            if val == '#':
                return None
            root = TreeNode(int(val))
            root.left = self.build(vals)
            root.right = self.build(vals)
            return root
        return self.build(vals)

#[1, ',', 2, ',', 4, ',', ',', ',', 5, ',', ',', ',', 3, ',', 6, ',', ',', ',', 7, ',', ',']
if __name__=="__main__":
    A1 = TreeNode(1)
    A2 = TreeNode(2)
    A3 = TreeNode(3)
    A4 = TreeNode(4)
    A5 = TreeNode(5)
    A6 = TreeNode(6)
    A7 = TreeNode(7)

    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    A3.left=A6
    A3.right=A7

    solution = Solution()
    ans=solution.Serialize(A1)
    print(ans)
    root=solution.Deserialize(ans)
    res=solution.Serialize(root)
    print(res)

62.二叉搜索树中的第K个节点
题目:给定一棵二叉搜索树,请找出其中的第k小的结点。例如(5,3,7,2,4,6,8)中,按结点数值大小顺序第三小结点的值为4。
思路:中序遍历后,返回第K个节点值。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    # 返回对应节点TreeNode
    def KthNode(self, pRoot, k):
        
        res=[]
        if not pRoot:
            return None
        self.order(pRoot,res)
        if len(res)<k or k<=0:
            return None
        else:
            return res[k-1]

    def order(self,root,res):
        if not root:
            return
        self.order(root.left,res)
        res.append(root)
        self.order(root.right,res)

if __name__=='__main__':
    A1 = TreeNode(5)
    A2 = TreeNode(3)
    A3 = TreeNode(7)
    A4 = TreeNode(2)
    A5 = TreeNode(4)
    A6 = TreeNode(6)
    A7 = TreeNode(8)

    A1.left=A2
    A1.right=A3
    A2.left=A4
    A2.right=A5
    A3.left=A6
    A3.right=A7

    k=3
    solution = Solution()
    ans=solution.KthNode(A1,k)
    print(ans)

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

class Solution:
    def __init__(self):
        self.data=[]
    def Insert(self, num):
        
        self.data.append(num)
        self.data.sort()
    def GetMedian(self):
        
        length=len(self.data)
        if length%2==0:
  return (self.data[length//2]+self.data[length//2-1])/2.0
        else:
            return self.data[int(length//2)]

64.滑动窗口的最大值
题目:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。

class Solution:
    def maxInWindows(self, num, size):
        
        if size==0 or num==[]:
            return []
        res=[]
        for i in range(0,len(num)-size+1):
            tempnum=[]
            for j in range(i,i+size):
                tempnum.append(num[j])
            res.append(max(tempnum))
        return res

if __name__=="__main__":
    solution=Solution()
    num=[2,3,4,2,6,2,5,1]
    size=3
    ans=solution.maxInWindows(num,size)
    print(ans)

65.矩阵中的路径
题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。例如 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):
        
        for i in range(0,rows):
            for j in range(0,cols):
                if matrix[i*rows+j]==path[0]:
                    if self.find_path(list(matrix),rows,cols,path[1:],i,j):
                        return True
        return False

    def find_path(self,matrix,rows,cols,path,i,j):
        if not path:
            return True
        matrix[i*cols+j]=0
        if j+1<cols and matrix[i*cols+j+1]==path[0]:
            return self.find_path(matrix,rows,cols,path[1:],i,j+1)
        elif j-1>=0 and matrix[i*cols+j-1]==path[0]:
            return self.find_path(matrix, rows, cols, path[1:], i, j - 1)
        elif i+1<rows and matrix[(i+1)*cols+j]==path[0]:
            return self.find_path(matrix, rows, cols, path[1:], i+1, j)
        elif i-1>=0 and matrix[(i-1)*cols+j]==path[0]:
            return self.find_path(matrix, rows, cols, path[1:], i-1, j)
        else:
            return False

if __name__=='__main__':
    solution=Solution()
    matrix='ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS'
    rows=5
    cols=8
    path='SGGFIECVAASABCEHJIGQEMS'
    ans=solution.hasPath(matrix,rows,cols,path)
    print(ans)

66.机器人的运动范围
题目:地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
思路:对未走过的路径进行遍历,搜索所有的路径值。

class Solution:
    def __init__(self):
        self.vis = {}

    def movingCount(self, threshold, rows, cols):
        
        return self.moving(threshold, rows, cols, 0, 0)

    def moving(self, threshold, rows, cols, row, col):
        rowans,colans=0,0
        rowtemp,coltemp=row,col
        while rowtemp>0:
            rowans=rowans+rowtemp%10
            rowtemp=rowtemp//10
        while coltemp>0:
            colans=colans+coltemp%10
            coltemp=coltemp//10

        if rowans+colans>threshold:
            return 0
        if row >= rows or col >= cols or row < 0 or col < 0:
            return 0
        if (row, col) in self.vis:
            return 0
        self.vis[(row, col)] = 1

        return 1 + self.moving(threshold, rows, cols, row - 1, col) +\
               self.moving(threshold, rows, cols, row + 1,col) + \
               self.moving(threshold, rows,cols, row,col - 1) + \
               self.moving(threshold, rows, cols, row, col + 1)


if __name__=='__main__':
    solution=Solution()
    threshold=10
    rows,cols=1,100
    ans=solution.movingCount(threshold,rows,cols)
    print(ans)

class Solution:#5
    def __init__(self):
        self.Stack1=[]
        self.Stack2=[]
    def push(self, node):
        self.Stack1.append(node)
    def pop(self):
        if self.Stack2==[]:
            while self.Stack1:
                self.Stack2.append(self.Stack1.pop())
            return self.Stack2.pop()
        return self.Stack2.pop()
def SubT(self, pRoot1, pRoot2):#17
    result = False
    if pRoot1 != None and pRoot2 != None:
        if pRoot1.val == pRoot2.val:
            result = self.T1haveT2(pRoot1,pRoot2)
        if not result:
            result = self.SubT(pRoot1.left,pRoot2)
        if not result:
            result = self.SubT(pRoot1.right,pRoot2)
    return result
def T1haveT2(self,pRoot1,pRoot2):
    if pRoot2 == None:
        return True
    if pRoot1 == None:
        return False
    if pRoot1.val != pRoot2.val:
        return False
    return self.T1haveT2(pRoot1.left, pRoot2.left)\
         and self.T1haveT2(pRoot1.right, pRoot2.right)
def Mirror(self, root):#18
    if root == None:
        return
    if root.left == None and root.right == None:
        return root
    ptemp = root.left
    root.left = root.right
    root.right = ptemp
    self.Mirror(root.left)
    self.Mirror(root.right)
class Solution(object): #20
    def __init__(self):
        self.minstack=[]
        self.stack=[]
    def push(self,num):
        self.stack.append(num)
        if self.minstack==[] or num<self.Min:
            self.minstack.append(num)
        else:
            temp=self.Min
            self.minstack.append(temp)
    def pop(self,num):
        if not self.minstack or not self.stack:
            return
        self.minstack.pop()
        self.stack.pop()
    def Min(self):
        return self.minstack[-1]
def IsPopOrder(pushV, popV): #21
    if pushV == [] or popV == []:
        return False
    stack = []
    for i in pushV:
        stack.append(i)
        while len(stack) and stack[-1] == popV[0]:
            stack.pop()
            popV.pop(0)
    if len(stack): 
        return False
    else:
        return True    
IsPopOrder([1,2,3,4,5],[4,3,5,2,1])
def SeqOfBST(self, seq):#23
    if seq == []:
        return False
    length = len(seq)
    root = seq[-1]
    for i in range(length):
        if seq[i] > root:
            break
    for j in range(i, length):
        if seq[j] < root:
            return False
    left = True
    if i > 0:
        left = SeqOfBST(seq[:i])
    right = True
    if j < length - 1:
        right = SeqOfBST(seq[i:length-1])
    return left and right        
def Clone(self, pHead):#25
    if not pHead:
        return None
    #创建新链表
    pCur=pHead
    while pCur:
        pCur_next=pCur.next
        newnode=RandomListNode(pCur.label)
        newnode.next=pCur_next
        pCur.next=newnode
        pCur=pCur_next
    #改变新链表的random指针
    pCur=pHead
    while pCur:
        pCur_random=pCur.random
        newnode=pCur.next
        if pCur_random:
            newnode.random=pCur_random.next
        pCur=newnode.next
    pCur=pHead
    result=pHead.next
    #分离两链表
    while pCur:
        newnode=pCur.next
        pCur_next=newnode.next
        pCur.next=pCur_next
        if pCur_next:
            newnode.next=pCur_next.next
        else:
            newnode.next=None
        pCur=pCur.next
    return result
class Solution:#26
    def __init__(self):
        self.listHead = None
        self.listTail = None
    def Convert(self, pRootOfTree):
        if pRootOfTree==None:
            return
        self.Convert(pRootOfTree.left)
        if self.listHead==None:
            self.listHead = pRootOfTree
            self.listTail = pRootOfTree
        else:
            self.listTail.right = pRootOfTree
            pRootOfTree.left = self.listTail
            self.listTail = pRootOfTree
        self.Convert(pRootOfTree.right)
        return self.listHead
def GetLeast(self, tinput, k):#29
    # write code here
    if not tinput or k > len(tinput):
        return []
    tinput = self.quick_sort(tinput)
    return tinput[:k]
def quick_sort(self,lst):
    if not lst:
        return []
    pivot = lst[0]
    leftnum=[x for x in lst[1: ] if x < pivot]
    rightnum=[x for x in lst[1: ] if x >= pivot]
    left = self.quick_sort(leftnum)
    right = self.quick_sort(rightnum)
return left + [pivot] + right  
def Number(self, n):#31
    count=0
    for i in range(1,n+1):
        while i:
            if i%10==1:
                count+=1
            i=i/10
    return count
def Number1(self, n):
    count, m =0, 1
    while m <= n:
        count += (n // m + 8) // 10 * m + (n // m % 10 == 1) * (n % m + 1)
        m*=10
    return count      
def largestNumber(self, nums): #32
    if len(nums) == 0 or nums == None:
        return 0
    if len(nums) == 1:
        return str(nums[0])
    res = [nums[0]]
    for i in range(1,len(nums)):
        for j in range(len(res)):
            flag = False  
            if str(nums[i])+str(res[j])
               >str(res[j])+str(nums[i]):
                flag = True
                res.insert(j,nums[i])
                break
        if flag == False:#都没成功排在最后面
            res.append(nums[i])
    res_str = ""
    for i in res:
        res_str+=str(i)
    return str(int(res_str))
def Ugly(index):#33
    if not index:
        return 0
    uglyn = [1]*index
    next = 1 
    index2 = 0
    index3 = 0
    index5 = 0
    while next < index:
        minValue = min(uglyn[index2]*2,
uglyn[index3]*3, uglyn[index5]*5)
        uglyn[next] = minValue
        while uglyn[index2]*2 <= uglyn[next]:
            index2 += 1 
        while uglyn[index3]*3 <= uglyn[next]:
            index3 += 1 
        while uglyn[index5]*5 <= uglyn[next]:
            index5 += 1
        next += 1
    return uglyn[-1]
def FirstNotRepeatingChar(self, s):#34
    if not s:
        return -1
    store = {}
    lis = list(s)
    for i in lis:
        if i not in store.keys():
            store[i] = 0
        store[i] += 1
    for i in lis:
        if store[i] == 1:
            return s.index(i)
    return -1
def FindContinuousSequence(tsum):#41
    small, big,res = 1, 2, []
    csum = small + big
    while small < big:
        if csum > tsum:
            csum -= small
            small += 1
        else:
          if csum == tsum:
            res.append([i for i in range(small,big+1)])
            big += 1
            csum += big
    return res
def bat(nums):#45
    transdict = {'A':1,'J':11,'Q':12,'K':13}
    for i in range(len(nums)):
        if nums[i] in transdict.keys():
            nums[i] = transdict[nums[i]]
    nums.sort()
    b=None #期待的数
    a=nums.count(0)
    for num in nums[a:]:
        if b==None:#第一个不是零的数
            b=num+1
            continue
        if num!=b:
            while num!=b:
                if a!=0:
                    b+=1
                    a-=1
                else:
                    return False
            b+=1
        else :
            b+=1       
    return True
def lastnum(c,m): #46自己写的,感觉想的很好
    num=[i for i in range(c)]
    while len(num)>1:
        n=m%len(num)
        if n==0:
            num.pop(-1)
        else:
            num=num[n:]+num[:n-1]
    return num
aaa = lastnum(5,3)
def Add(self, num1, num2):#48
    # write code here
    while num2 != 0:
        temp = num1 ^ num2
        num2 = (num1 & num2) << 1
        num1 = temp & 0xFFFFFFFF
    return num1 if num1 >> 31 == 0 else num1 - 4294967296
def duplicate(self, numbers, duplication):#50
    if not numbers or len(numbers) < 0:
        return False
    for i in numbers:
        if i < 0 or i > len(numbers) - 1:
            return False
    for i in range(len(numbers)):
        while numbers[i] != i:
            if numbers[i] == numbers[numbers[i]]:
                duplication[0] = numbers[i]
                return True
            else:
                idx = numbers[i]
                numbers[i],numbers[idx] = numbers[idx],numbers[i]
    return False
def multiply(self, A):#51
    if not A or len(A) <= 0:
        return
    length = len(A)
    lis = [1] * length
    for i in range(1,length):
        lis[i] = lis[i-1] * A[i-1]
    temp = 1
    for i in range(length-2,-1,-1):
        temp = temp * A[i+1]
        lis[i] *= temp
return lis
def build(nums):#自己写
    pre=[1 for i in range(len(nums))]
    last=[1 for i in range(len(nums))]
    B=[0 for i in range(len(nums))]
    for i in range(1,len(nums)):
        pre[i]=pre[i-1]*nums[i-1]
    for i in range(len(nums)-2,-1,-1):
        last[i]=last[i+1]*nums[i+1]
    for i in range(len(nums)):
        B[i]=pre[i]*last[i]
    return B
B=build([2,3,4,5,6])

当前节点有右子树的话,当前节点的下一个结点是右子树中的最左子节点;
当前节点无右子树但是是父节点的左子节点,下一个节点是当前结点的父节点;
当前节点无右子树而且是父节点的右子节点,则一直向上遍历,
直到找到最靠近的一个祖先节点p,p是其父节点的左子节点,
那么输入节点的下一个结点就是p的父节点

class TreeLinkNode:#57
    def __init__(self, x):
        self.val = x        self.left = None
        self.right = None   self.next = None
class Solution:
def GetNext(self, p):
    if p is None:
        return 
    pNext = None
    if p.right:
        p = p.right
        while p.left:
            p = p.left
        pNext = p
    else:
        if p.next and p.next.left == p:
            pNext = p.next
        elif p.next and p.next.right == p:
            p = p.next
            while p.next and p.next.right == p:
                p = p.next  
            if p.next:
                pNext = p.next
    return pNext
def windows(nums,n):#64
    listcup=[]
    for i in range(len(nums)-n+1):
        tem=nums[i:i+n]
        listcup.append(max(tem))
    return listcup
def movingCount(self, threshold, rows, cols):#66
    matrix = [[0 for i in range(cols)] for j in range(rows)]
    def findgrid(i, j):
        count = 0
        if 0<=i<rows and 0<=j<cols and judge(i, j) and matrix[i][j] == 0: 
            # matrix[i][j]==0表示没走过这一格
            matrix[i][j] = 1  # 表示已经走过了
            count = 1 + findgrid(i, j+1) + findgrid(i, j-1) 
                     + findgrid(i+1, j) + findgrid(i-1, j)
        return count
    def judge(i, j):
        if sum(map(int, str(i) + str(j))) <= threshold:
            return True
        else:
            return False
    count = findgrid(0, 0)
    print(matrix)
    return count,matrix
sum(map(int, str(i) + str(j)))i,j是超过1位的数也可以完美得到坐标位置和!

# 冒泡-越到后面越大
def bubble_sort(lst):
    for j in range(len(lst)-1,0,-1):
        for i in range(j):
            if lst[i] > lst[i+1]:
                lst[i],lst[i+1]=lst[i+1], lst[i]
    return lst
# 选择-找最小的放在前面
def selection_sort(alist):
    n = len(alist)
    for i in range(n-1):
        min_index = i
        for j in range(i+1, n):
            if alist[j]< alist[min_index]:
                min_index = j
        if min_index != i:
         alist[i],alist[min_index]=alist[min_index],alist[i]
# 插入-拿来一个元素放前面有序序列中
def insert_sort(alist):
    for i in range(1, len(alist)):
        for j in range(i, 0, -1):
            if alist[j] < alist[j-1]:
                alist[j],alist[j-1]=alist[j-1],alist[j]
# 希尔排序-拿一个元素放前面有序序列中mid->1的插入排序
def ShellSort(lst):
    def shellinsert(arr,d):
        n=len(arr)
        for i in range(d,n):
            j=i-d
            temp=arr[i]         # 记录要出入的数
            while(j>=0 and arr[j]>temp): # 从后向前,找比其小的数的位置
                arr[j+d]=arr[j] 
                j-=d
            if j!=i-d:
                arr[j+d]=temp         
    n=len(lst)
    d=n//2
    while d>=1:
        shellinsert(lst,d)
        d=d//2
    return lst
# 快速排序
def QuickSort(lst):
    def partition(arr, left, right):
        key = left  
        while left < right:
            while left < right and arr[right] >= arr[key]:
                right -= 1
            while left < right and arr[left] <= arr[key]:
                left += 1
            (arr[left], arr[right]) = (arr[right], arr[left])
        (arr[left], arr[key]) = (arr[key], arr[left])
        return left
    def quicksort(arr, left, right):  
        if left >= right:
            return
        mid = partition(arr, left, right)
        quicksort(arr, left, mid - 1)
        quicksort(arr, mid + 1, right)
    n = len(lst)
    quicksort(lst, 0, n - 1)
    return lst
# 堆排序-构建堆
def  HeapSort(lst):
    def heapadjust(arr,start,end):
        temp=arr[start]
        son=2*start+1
        while son<=end:
            if son<end and arr[son]<arr[son+1]:  #找出左右孩子节点较大的
                son+=1
            if temp>=arr[son]:  #判断是否为大顶堆
                break
            arr[start]=arr[son]     #子节点上移
            start=son         #继续向下比较
            son=2*son+1
        arr[start]=temp    #将原堆顶插入正确位置
        
    n=len(lst)
    #逆向建立大顶堆
    root=n//2-1  #最后一个非叶节点(完全二叉树中)
    while(root>=0):
        heapadjust(lst,root,n-1)
        root-=1
    #掐掉堆顶后调整堆
    i=n-1
    while(i>=0):
        (lst[0],lst[i])=(lst[i],lst[0])#lst[0]最大
        heapadjust(lst,0,i-1)  #调整剩余数组成的堆
        i-=1
    return lst

思路

核心算法依旧是中序遍历
不是从根节点开始,而是从中序遍历得到的第一个节点开始,定义两个辅助节点listHead(链表头节点)、listTail(链表尾节点)。事实上,二叉树只是换了种形式的链表;listHead用于记录链表的头节点,用于最后算法的返回;listTail用于定位当前需要更改指向的节点。了解了listHead和listTail的作用,代码理解起来至少顺畅80%。

设定整数点(如1、10、100等等)作为位置点m(对应n的各位、十位、百位等等),分别对每个数位上有多少包含1的点进行分析。
根据设定的整数位置,对n进行分割,分为两部分,高位n//m,低位n%m
当i表示百位,且百位对应的数>=2,如n=31456,m=100,则a=314,b=56,此时百位为1的次数有a/10+1=32(最高两位0~31),每一次都包含100个连续的点,即共有(a/10+1)100个点的百位为1
当i表示百位,且百位对应的数为1,如n=31156,m=100,则a=311,b=56,此时百位对应的就是1,则共有a/10(最高两位0-30)次是包含100个连续点,当最高两位为31(即a=311),本次只对应局部点00~56,共b+1次,所有点加起来共有(a/10
100)+(b+1),这些点百位对应为1
当i表示百位,且百位对应的数为0,如n=31056,m=100,则a=310,b=56,此时百位为1的次数有a/10=31(最高两位0~30)
综合以上三种情况,当百位对应0或>=2时,有(a+8)/10次包含所有100个点,还有当百位为1(a%101),需要增加局部点b+1
之所以补8,是因为当百位为0,则a/10
(a+8)/10,当百位>=2,补8会产生进位位,效果等同于(a/10+1)

注意,这篇文章是我大学期间学习用的代码,我只是做了一个总结,大多数代码来源于网络,侵权的话请联系我。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值