leetcode剑指offer题目解答

python实现剑指offer算法题【1】:找出数组中重复的数字

一、思路

  1. 排序,将数组排序之后,再找出重复的数字,排序一个长为n的数组所需要的时间是0(nlogn)。
  2. 哈希表,Python用集合也可以实现,因为Python的set集合是不允许重复字符出现的。这样时间复杂度就是0(n),代价就是一个哈希表的空间复杂度。

二、代码

class Solution(object):
 
    # 思路一:排序
   def findRepeatNumber(self, nums):
        nums.sort()
        for i in range(len(nums)):
            if (nums[i] == nums[i + 1]):
                print(nums[i])
                return nums[i]      

 # 思路二:哈希表,Python中集合有相同作用
    def findRepeatNumber2(self,nums):
        b = set()
        for num in a:
            if num in b:
                return num
            else:
                b.add(num)

【2】:把字符串 s 中的每个空格替换成"%20"

一、思路

  1. 先将字符串按照空格分开形成单个字符串,再将每个字符串用%20连接起来。
  2. 遍历字符串,遇到空格时换成%20,非空格时直接连接。

二、代码

class Solution(object):
 
    # 思路一:
   def replaceSpace(self, s):
        li=s.split(' ')
        ss=''
        for i in range(len(li)):
            if i < len(li)-1:
                ss=ss+li[i]+'%20'
        ss=ss+li[-1]
        return ss   

 # 思路二:
   def replaceSpace(self, s):
        ss=''
        for i in s:
            if i == ' ':
                ss=ss+'%20'
            else:
                ss=ss+i
        return ss

【3】:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)

一、思路

  1. 从头开始遍历链表,并将链表节点中的数值添加到列表中,再将列表中的指逆转,再返回结果。

二、代码

class Solution(object):
    def reversePrint(self, head):
        a=[]
        while head is not None:
            a.append(head.val)
            head=head.next
        a.reverse()
        return a

【4】斐波那契数列(斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1

一、思路

  1. 每次都由前两个相邻的数相加得到第三个数,最终求得第n个数。
  2. 注:普通的采用迭代法的斐波那契数列会超时,故用列表来记录已求出的前两个值并相加求出后一个值。

二、代码

#思路一
class Solution(object):
    def fib(self,n):
        arr = [0,1]
        while len(arr) <= n:
            arr.append( arr[-1]+arr[-2] )
        return arr[n]%1000000007

#思路二:占用内存更小
class Solution(object):
    def fib(self, n):
        n1 = 0
        n2 = 1
        if n == 0:
            return 0
        elif n == 1: 
            return 1
        for i in range(2, n+1):
            temp = n1 + n2
            n1 = n2
            n2 = temp
        return temp

【5】旋转数组的最小数字:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

一、思路

  1. 找列表中的最小值。

二、代码

class Solution(object):
    def minArray(self, numbers):
        min=numbers[0]
        for i in range(len(numbers)):
            if numbers[i]<min:
                min=numbers[i]
        return min

【6】青蛙跳台阶问题:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。答案需要取模1e9+(1000000007),如计算初始结果为:1000000008,请返回 1。

一、思路

  1. 跟斐波那契数列问题类似,需要我们首先从题目中找到求解的思路。
  2. 具体分析:青蛙一次只能跳一个或者两个台阶,如果青蛙下一步就跳到了第n个台阶上,那么青蛙当前离第n个台阶要么只有一个台阶的距离,要么有两个台阶的距离。所以到达第n个台阶的跳步总数等于到达第n-1个台阶的跳步总数+到达第n-2个台阶的跳步总数。

二、代码

class Solution(object):
    def numWays(self, n):
        if n==0:
            return 1
        if n==1:
            return 1
        if n==2:
            return 2
        if n>2:
            li=[1,1,2]
            for i in range(3,n+1):
                li.append((li[-1]%1000000007+li[-2]%1000000007)%1000000007)
        return li[n]

【7】二维数组中的查找:在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

一、思路

  1. https://blog.csdn.net/qq_39447127/article/details/104492158

二、代码

class Solution(object):
    def findNumberIn2DArray(self, array, target):
        n=len(array)
        if n==0:
            return False
        m=len(array[0])
        if m==0:
            return False
        hang=n-1
        lie=0
        while hang>=0 and lie<=m-1:
            if array[hang][lie]<target:
                lie+=1
            elif array[hang][lie]>target:
                hang-=1
            else:#array[hang][lie]==target:
                return True
        return False

【8】第一次只出现一个的字符:在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

一、思路

  1. 列表1,2分别记录所有字符集以及出现过2次及其以上的字符。
  2. 再对两个列表中的值进行判断。

二、代码

class Solution(object):
    def firstUniqChar(self, s):
        if len(s)==0:
            return " "
        li=[]#记录单次的
        exit=[]#记录重复的,只记录一次
        for i in s:
            if i not in li:
                li.append(i)
            elif (i in li) and (i not in exit):
                exit.append(i)
        if len(li)==len(exit):#不存在出现一次的字符,所有字符都出现过多次
            return " "
        else:
            if len(li)!=0 and len(exit)==0:#不存在出现多次的字符,所有字符只出现一次
                return li[0]#第一个即为所求
            else:
                for i in li:#即存在出现只出现一次的又存在出现多次的,则取第一个出现一次的
                    if i not in exit:
                        return i

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

一、思路

1.栈1用来做存储栈,栈2用来调换顺序。
2.元素入队列时进入栈1,出队列时从栈2中出来。具体如下:入队列时进入栈1;出队列时当栈2中不空时就从栈2中出栈一个元素,当栈2为空时若栈1也为空则返回-1,当栈2为空栈1不为空时先把栈1中的元素按照出栈顺序一次入栈2,再从栈2出栈一个元素。

二、代码

class CQueue(object):

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

    def appendTail(self, value):
        """
        :type value: int
        :rtype: None
        """
        if value:
            self.stack1.append(value)

    def deleteHead(self):
        """
        :rtype: int
        """
        '''if len(self.stack1)==0:
            if len(self.stack2)==0:
                return -1
            else:
                return self.stack2.pop()
        else:
            if len(self.stack2)==0:
                while len(self.stack1)>0:
                    self.stack2.append(self.stack1.pop())
                return self.stack2.pop()
            else:
                return self.stack2.pop()'''
        if self.stack2:
            return self.stack2.pop()
        else:
            if self.stack1:
                while len(self.stack1) > 0:
                    self.stack2.append(self.stack1.pop())
                return self.stack2.pop()
            else:
                return -1

【10】重建二叉树:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

在这里插入图片描述

一、思路

引https://blog.csdn.net/u013129109/article/details/80590742

二、代码

# Definition for a binary tree node.
'''class TreeNode(object):
     def __init__(self, x):
         self.val = x
         self.left = None
         self.right = None'''

class Solution(object):
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        if len(preorder)==0:
            return None
        elif len(preorder)==1:
            return TreeNode(preorder[0])

        else:
            res=TreeNode(preorder[0])
            pos=inorder.index(preorder[0])
            res.left=self.buildTree(preorder[1:pos+1],inorder[:pos])
            res.right=self.buildTree(preorder[pos+1:],inorder[pos+1:])
            return res

【11】矩阵中的路径

在这里插入图片描述

一、思路

1.分别以数组中的每个元素为起点,判断从该起点开始,是否包含给定的字符串的路径。方法采用递归即可。

二、代码

class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        hang=len(board)
        lie=len(board[0])
        for i in range(hang):
            for j in range(lie):
                if board[i][j]==word[0] and self.find(board,hang,lie,word[1:],i,j):#找到第一个字符则从第二个字符开始继续往下找
                    return True
                else:
                    continue
        return False

    def find(self,board,hang,lie,word,i,j):
        if not word:
            return True
        board[i][j]='0'#已经走过的位置做上标记,防止后续回过去
        if j+1<=lie-1 and board[i][j+1]==word[0]:#往右走找到了字符串中的第一个字符
            return self.find(board,hang,lie,word[1:],i,j+1)
        elif j-1>=0 and board[i][j-1]==word[0]:#往左走找到了字符串中的第一个字符
            return self.find(board,hang,lie,word[1:],i,j-1)
        elif i+1<=hang-1 and board[i+1][j]==word[0]:#往下走找到了字符串中的第一个字符
            return self.find(board,hang,lie,word[1:],i+1,j)
        elif i-1>=0 and board[i-1][j]==word[0]:#往上走找到了字符串中的第一个字符
            return self.find(board,hang,lie,word[1:],i-1,j)
        else:
            return False

【12】机器人的运动范围:地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

一、思路

1.本题与上一题思想一致,都是使用回溯法解决问题,只不过对于位置的约束条件的不同。

二、代码

class Solution(object):
    def movingCount(self, m, n, k):
        mat = [[0 for i in range(m)] for j in range(n)]
        return self.ifgo(m,n,0,0,k,mat)
    def Total(self, i, j,k):#求和方法一
        total=i+j
        total=str(total)
        sum=0
        for i in total:
            sum+=int(i)
        if sum<=k:
            return True
        else:
            return False
     '''
     def Total(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 ifgo(self,m,n,i,j,k,mat):
        t=0
        if i <= m - 1 and i >= 0 and j <= n - 1 and j >= 0 and mat[i][j] == 0 and self.Total(i , j,k):
            mat[i][j]=1
            t = 1 + self.ifgo(m, n, i, j-1, k,mat) \
                    + self.ifgo(m, n, i, j+1, k,mat) \
                    + self.ifgo(m, n, i-1, j, k,mat) \
                    + self.ifgo(m, n, i+1, j, k,mat)
        return t

【13】剪绳子:给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

一、思路

1.https://blog.csdn.net/mabozi08/article/details/88776796

二、代码

class Solution(object):
    def cuttingRope(self, n):
        """
        :type n: int
        :rtype: int
        """
        if (n < 2):
            return 0
        if (n == 2):
            return 1
        if (n == 3):
            return 2
            # 当length>=4的时候,自身不剪比剪的结果大
        products = [1] * (n + 1)
        products[0] = 0
        products[1] = 1
        products[2] = 2
        products[3] = 3
        max = 0
        for i in range(4, n + 1):
            max = 0
            for j in range(1, i // 2 + 1):
                product = products[j] * products[i - j]
                if max < product:
                    max = product
            products[i] = max
        max = products[n]
        return max

【14】剪绳子:给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

一、思路

1.https://blog.csdn.net/mabozi08/article/details/88776796

二、代码

class Solution(object):
    def cuttingRope(self, n):
        """
        :type n: int
        :rtype: int
        """
        if (n < 2):
            return 0
        if (n == 2):
            return 1
        if (n == 3):
            return 2
            # 当length>=4的时候,自身不剪比剪的结果大
        products = [1] * (n + 1)
        products[0] = 0
        products[1] = 1
        products[2] = 2
        products[3] = 3
        max = 0
        for i in range(4, n + 1):
            max = 0
            for j in range(1, i // 2 + 1):
                product = products[j] * products[i - j]
                if max < product:
                    max = product
            products[i] = max
        max = products[n]
        return max%1000000007

【15】二进制中1的个数:请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

一、思路

1.先求输入整数的二进制类型,再按照字符串统计二进制数中1的个数。

二、代码

class Solution(object):
    def hammingWeight(self, n):
        """
        :type n: int
        :rtype: int
        """
        sum=0
        s=self.binary(n)
        for i in s:
            if i=='1':
                sum+=1
        return sum
    def binary(self,n):
        s=''
        while n!=0:
            m=n%2
            s+=str(m)
            n=n//2
        return s

【16】数值的整数次方:实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,x^n)。不得使用库函数,同时不需要考虑大数问题。

一、思路

1.a的n次方等于a的n/2次方^2(当n为偶数时)
2.a的n次方等于a的(n-1)/2次方^2再乘以a(当n为奇数时)
(注:以递归法求解提交时显示溢出)

二、代码

#递归法:
class Solution(object):
    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """
        if x==0:
            return 0
        else:
            if n==0:
                return 1
            elif n==1:
                return x
            elif n>1:
                if n%2==0:
                    return self.myPow(x,n//2)**2
                elif n%2==1:
                    return self.myPow(x,n//2)**2*x
            elif n<0:
                return 1/self.myPow(x,-n)
#提交通过的解法:
class Solution(object):
    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """
        if x==0:
            return 0
        else:
            if n==0:
                return 1
            elif n==1:
                return x
            elif n>1:
                if n%2==0:
                    res=self.myPow(x,n>>1)
                    res*=res
                    return res
                elif n%2==1:
                    res = self.myPow(x, n >> 1)
                    res *= res
                    res*=x
                    return res
            elif n<0:
                return 1/self.myPow(x,-n)

【17】打印从1到最大的n位数:输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。

一、思路

1.即依次打印1到10^n-1。

二、代码

class Solution(object):
    def printNumbers(self, n):
        """
        :type n: int
        :rtype: List[int]
        """
        num=[]
        for i in range(1,10**n):
            num.append(i)
        return num

【18】删除链表的节点:给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。

一、思路

1.如果链表为空直接返回None。
2.链表头节点的数值等于所删除的值时,直接返回第二个节点。
3.剩下的情况就直接按照顺序依次进行判断,如果为删除的值,直接删除操作后,返回头节点。

二、代码

class Solution(object):
    def deleteNode(self, head, val):
        """
        :type head: ListNode
        :type val: int
        :rtype: ListNode
        """
        if head is None:#链表为空
            return None
        if head.val==val:#头节点即为要删除的节点
            return head.next
        h = head#用h记录头节点的位置
        while h!=None:
            if h.next.val==val:
                h.next=h.next.next
                return head
            h=h.next
        return head

【19】正则表达式匹配:请实现一个函数用来匹配包含’. ‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"和"ab*a"均不匹配。

一、思路

1.https://blog.csdn.net/u010005281/article/details/80200492

二、代码

class Solution(object):
    def isMatch(self, s, p):
        if s == p:
            return True
        if len(p) > 1 and p[1] == '*':
            if s and (s[0] == p[0] or p[0] == '.'):
                return self.match(s, p[2:]) or self.match(s[1:], p)
            else:
                return self.match(s, p[2:])
        elif s and p and (s[0] == p[0] or p[0] == '.'):
            return self.match(s[1:], p[1:])
        return False

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

一、思路

1.一言难尽(哭。
2.代码还是有问题,先做个记录。

二、代码

class Solution(object):
    def isNumber(self, s):
       
        if len(s)==0:
            print(len(s))
            return False
        elif len(s)==1 :
            if s[0]=='0' or s[0]=='1' or s[0]=='2' or s[0]=='3' or s[0]=='4' or s[0]=='5' or s[0]=='6' or s[0]=='7' or s[0]=='8' or s[0]=='9':
                return True
            else:
                return False
        elif len(s)>=2:
            if s[0]=='.':
                for i in range(1,len(s)):
                    if s[i] not in '1234567890':
                        #print('1')
                        return False
                #print('2')
                return True
            elif s[0]==' ':
                mm=0
                nn=-1
                for i in range(1,len(s)):
                    if s[i]!=' ':
                        mm=i
                print(s[mm:])
                return self.isnumber(s[mm:])
            elif s[0] == '-' or s[0] == '+':
                return self.isnumber(s[1:])
            elif s[-1]=='.':
                for i in range(len(s)-1):
                    if s[i] not in '0123456789':
                        return False
                return True
            else:
                #print('111')
                return self.isnumber(s)

    def isnumber(self,s):
        dot=True
        E=True

        if len(s) == 1 :
            if s[0] in '0123456789':
                return True
            else:
                return False
        elif len(s)==2:
            if (s[0] in 'Ee') and (s[1] in '123456789'):
                return False
            elif (s[0] in '0123456789') and (s[1] in ' 0123456789'):
                return True
            else:
                return False
        elif len(s)>=3:
            if (s[-1] in 'eE') or s[-1]=='.' or s[-1]=='-' or s[-1]=='+' or (s[-1] in '+-' and s[-2] in 'Ee') or s[0]=='.':
                return False
            for i in range(len(s)):
                if s[i] not in '0123456789eE.':
                    return False
                else:
                    if dot and s[i] == '.' and E:  # 出现一次小数点(e和小数点不能同时有)
                        dot = False
                    elif dot == False and s[i] == '.':  # 不能再有小数点了
                        return False
                    elif s[i] in 'Ee' and E:#出现E
                        E = False
                    elif s[i] in 'Ee' and E == False:#又出现e
                        print('nn')
                        return False
                    elif s[i] == '-' and (s[i - 1]!='E' or s[i-1]!='e'):  # -前面不是e
                        return False
                    elif s[i] == '-' and (s[i - 1] in 'Ee') and (s[i + 1] in '123456789'):#-前面是e后面是数
                        continue
                    elif s[i] in '0123456789.eE':
                        continue
        return True

【21】调整数组顺序使奇数位于偶数前面:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

一、思路

1.遍历数组将奇数值放入一个列表中,偶数值放入一个列表中,再将两个列表按照奇数值数组在前,偶数值数组在后的顺序合并。

二、代码

class Solution(object):
    def exchange(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        ji=[]
        ou=[]
        for i in nums:
            if i%2==1:
                ji.append(i)
            else:
                ou.append(i)
        result=ji+ou
        return result

【22】链表中倒数第k个节点:输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

在这里插入图片描述

一、思路

1.先遍历链表获取链表长度,再依次遍历链表直至倒数第k个,将该节点返回。

二、代码

class Solution(object):
    def getKthFromEnd(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        lenh=0
        if head!=None:
            hh=head
            while hh!=None:
                lenh+=1
                hh=hh.next
        if k>=lenh:
            return head
        h=head
        num=0
        while h!=None:
            num+=1
            if num==lenh-k+1:
                return h
            h=h.next

【23】反转链表:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

一、思路

1.遍历链表求链表长度并记录每个节点的值,再遍历链表逆转值的顺序。

二、代码

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        li = []
        lenh = 0
        if head != None:
            hh = head
            while hh != None:
                li.append(hh.val)
                lenh += 1
                hh = hh.next
        mm=head
        num=0
        while mm!=None:
            mm.val=li[lenh-num-1]
            num+=1
            mm=mm.next
        return head

【24】反转链表:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

一、思路

1.遍历链表求链表长度并记录每个节点的值,再遍历链表逆转值的顺序。

二、代码

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        li = []
        lenh = 0
        if head != None:
            hh = head
            while hh != None:
                li.append(hh.val)
                lenh += 1
                hh = hh.next
        mm=head
        num=0
        while mm!=None:
            mm.val=li[lenh-num-1]
            num+=1
            mm=mm.next
        return head

【25】合并两个排序的链表:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

在这里插入图片描述

一、思路

1.若其中一个链表为空时,则返回另一个链表,两个都为空时返回任意一个,两个都不为空时,遍历两个链表记录下所有数值再排序,然后再依次将排过序的值赋给每一个节点(赋值过程中要连接两个链表)。

二、代码

class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if l1==None:
            return l2
        elif l2==None:
            return l1
        elif l1==None and l2==None:
            return l1
        else:
            list1=[]
            list2=[]
            h1 = l1
            h2 = l2
            while h1 != None:
                list1.append(h1.val)
                h1 = h1.next
            while h2 != None:
                list2.append(h2.val)
                h2 = h2.next
            li = list1 + list2
            li.sort()
            f1 = l1
            f1.val = li[0]
            for i in li[1:]:
                if f1.next != None:
                    f1.next.val = i
                    f1 = f1.next
                else:
                    f1.next = l2
                    f1.next.val = i
                    f1 = f1.next
            return l1

【26】树的子结构:输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)B是A的子结构, 即 A中有出现和B相同的结构和节点值。

在这里插入图片描述

一、思路

1.https://www.cnblogs.com/ansang/p/11938132.html

二、代码

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution(object):
    def isSubStructure(self, pRoot1, pRoot2):
        if not pRoot1 or not pRoot2:
            return False
        return self.isrubtreeequl(pRoot1,pRoot2) or self.isSubStructure(pRoot1.left, pRoot2) or self.isSubStructure(pRoot1.right, pRoot2)
    def isrubtreeequl(self,root1,root2):
        if not root2:
            return True
        if not root1:
            return False
        return root1.val == root2.val and self.isrubtreeequl(root1.left,root2.left) and self.isrubtreeequl(root1.right,root2.right)

【27】二叉树的镜像:请完成一个函数,输入一个二叉树,该函数输出它的镜像。

在这里插入图片描述

一、思路

1.当树不为空时,交换左右子树,再分别对左右两个子树做递归处理。

二、代码

class Solution(object):
    def mirrorTree(self,root):
        if root:
            root.left,root.right = root.right,root.left
            if root.left:
                self.mirrorTree(root.left)
            if root.right:
                self.mirrorTree(root.right)
        return root

【28】对称的二叉树:请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

一、思路

1.判断根节点左子节点是否等于右子节点,若相等,则判断左子节点的结构是否与右子节点的结构是一致的,然后递归或循环。

二、代码

class Solution(object):
    def isSymmetric(self, pRoot):
        if pRoot == None:
            return True
        return  self.helper(pRoot, pRoot)
        
    def helper(self, root1, root2):
        if root1 == None and root2 == None:
            return True
        elif root1 == None or root2 == None:
            return False
        elif root1.val != root2.val:
            return False
        
        return self.helper(root1.left, root2.right) and self.helper(root1.right, root2.left)

【29】顺时针打印矩阵:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

在这里插入图片描述

一、思路

1.https://blog.csdn.net/qq_37888254/article/details/89673359

二、代码

class Solution(object):
    # matrix类型为二维列表,需要返回列表
    def spiralOrder(self, matrix):
        # write code here
        ans = []
        while matrix:
            ans.extend(matrix.pop(0))
            if not matrix or not matrix[0]:
                break
            matrix = self.rotate90(matrix)
        return ans
    def rotate90(self, matrix):
        rows = len(matrix)
        cols = len(matrix[0])
        newMatrix = []
        #以下代码将矩阵转置
        for c in range(cols):
            subcol = []
            for r in range(rows):
                subcol.append(matrix[r][c])
            newMatrix.append(subcol)
        #现在是将矩阵逆时针旋转90度
        newMatrix.reverse()
        return newMatrix

【30】栈的压入弹出序列:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。

在这里插入图片描述

一、思路

1.https://blog.csdn.net/weixin_42247922/article/details/103958355

二、代码


class Solution(object):
    def validateStackSequences(self, pushed, popped):
        """
        :type pushed: List[int]
        :type popped: List[int]
        :rtype: bool
        """
        stack=[]
        for i in pushed:
            stack.append(i)
            while stack and stack[-1]==popped[0]:
                popped.pop(0)
                stack.pop(-1)
        if stack:
            return False
        else:
            return True

【31】从上到下打印二叉树:从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

在这里插入图片描述

一、思路

1.因为是按照每一排从左到右的顺序来打印,所以用一个中间队列来存放节点,将根节点入队列。
2.当队列不为空时,从队列头部弹出一个元素(取其数值放入最终结果列表中),再对该元素进行判断,若其左子树不为空就将左子树放入中间队列,若其右子树不空将右子树放入中间队列。
3.重复2,直至队列为空

二、代码

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        li=[]#中间队列
        re=[]#结果队列
        if not root:
            return []
        li.append(root)
        while li:
            node=li.pop(0)
            re.append(node.val)
            if node.left:
                li.append(node.left)
            if node.right:
                li.append(node.right)
        return re  

【32】从上到下打印二叉树2:从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

在这里插入图片描述

一、思路

1.因为是按照每一排从左到右的顺序来打印,所以用一个中间队列来存放节点,将根节点入队列。
2.当队列不为空时,从队列中依次弹出所有元素(取其数值放入最终结果列表中),再对该元素进行判断,若其左子树不为空就将左子树放入中间队列,若其右子树不空将右子树放入中间队列。
3.重复2,直至队列为空

二、代码

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        li=[]#中间队列
        re=[]#结果队列
        li.append(root)
        while li:
            temp=[]
            for i in range(len(li)):
                node=li.pop(0)
                temp.append(node.val)
                if node.left:
                    li.append(node.left)
                if node.right:
                    li.append(node.right)
            re.append(temp)
        return re

【33】从上到下打印二叉树3:请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

在这里插入图片描述

一、思路

1.因为是按照每一排从左到右的顺序来打印,所以用一个中间队列来存放节点,将根节点入队列。
2.当队列不为空时,从队列中依次弹出所有元素并记录这是第几次弹出元素m(取其数值放入最终结果列表中),再对该元素进行判断,若其左子树不为空就将左子树放入中间队列,若其右子树不空将右子树放入中间队列。当m为奇数是正常弹出即可,当m为偶数时,要把弹出所有元素的中间队列逆转一下,再加入结果队列。
3.重复2,直至队列为空

二、代码

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        li=[]#中间队列
        re=[]#结果队列
        li.append(root)
        m=1
        while li:
            temp=[]
            for i in range(len(li)):
                node=li.pop(0)
                temp.append(node.val)
                if node.left:
                    li.append(node.left)
                if node.right:
                    li.append(node.right)
            if m%2==0:
                temp.reverse()
            re.append(temp)
            m+=1
        return re

【34】二叉搜索树的后序遍历序列:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

在这里插入图片描述

一、思路

1.https://blog.csdn.net/weixin_43988882/article/details/103333409

二、代码

class Solution:
    def verifyPostorder(self, sequence):
        # write code here
        length = len(sequence)
        if length == 0:
            return True
        root,index= sequence[-1],length-1
        for i in range(length-1):
            if sequence[i] > root:
                index = i
                break
        for temp in sequence[index:-1]:
            if temp <= root:
                return False
        left,right = True,True
        if index >0:
            left = self.verifyPostorder(sequence[:index])
        if index < length -1:
            right = self.verifyPostorder(sequence[index:-1])
        return left and right 

【34】复杂链表的复制:请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

在这里插入图片描述

一、思路

1.https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/solution/lian-biao-de-shen-kao-bei-by-z1m/

二、代码

class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        def dfs(head):
            if not head: return None
            if head in visited:
                return visited[head]
            # 创建新结点
            copy = Node(head.val, None, None)
            visited[head] = copy
            copy.next = dfs(head.next)
            copy.random = dfs(head.random)
            return copy
        visited = {}
        return dfs(head)

【35】数组中出现次数超过一半的数字:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。

一、思路

1.用集合处理一下列表用来记录出现的元素都有哪些,再遍历列表记录每个元素出现的次数,进行判断。

二、代码

class Solution(object):
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        num=len(nums)
        only=set(nums)
        for i in only:
            count=0
            for j in nums:
                if j==i:
                    count+=1
            if count*2>num:
                return i

【36】最小的k个数:输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

一、思路

1.对数组进行从小到大排序,再将前k个数返回。

二、代码

class Solution(object):
    def getLeastNumbers(self, arr, k):
        """
        :type arr: List[int]
        :type k: int
        :rtype: List[int]
        """
        if arr==None:
            return None
        if len(arr)<k:
            return None
        arr.sort()
        return arr[:k]

【37】连续子数组的最大和:输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。

一、思路

1.https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/solution/mian-shi-ti-42-lian-xu-zi-shu-zu-de-zui-da-he-do-2/

二、代码

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        for i in range(1,len(nums)):
            nums[i]+=max(nums[i-1],0)
        return max(nums)

【38】数据流中的中位数:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

例如,

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:

void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。

一、思路

1.初始化一个列表,再向列表中依次添加元素,再求中位数。

二、代码

class MedianFinder(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.li = []

    def addNum(self, num):
        """
        :type num: int
        :rtype: None
        """
        self.li.append(num)
    def findMedian(self):
        """
        :rtype: float
        """
        self.li.sort()
        length=len(self.li)
        if length%2==0:
            return 1.0*(self.li[length//2]+self.li[length//2-1])/2
        else:
            return self.li[length//2]
#题目要求
# Your MedianFinder object will be instantiated and called as such:
# obj = MedianFinder()
# obj.addNum(num)
# param_2 = obj.findMedian()

【39】字符串的排列:输入一个字符串,打印出该字符串中字符的所有排列。你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

一、思路

1.递归+去重。

二、代码

class Solution(object):
    def permutation(self, s):
        if not s:
            return []
        leng=len(s)
        if leng==1:
            return [s]
        elif leng==2:
            return [s,s[1]+s[0]]
        elif leng>=3:
            li=[]
            for i in range(leng):
                for j in self.permutation(s[:i]+s[i+1:]):#把前后两个分割的字符串合并成一个整体再递归调用函数
                    li.append(s[i]+j)
                    li.append(j+s[i])
                    #得出的结果有重复的
            re=[]
            for i in set(li):#去重
                re.append(i)
            return re

【40】两个链表的第一个公共节点:输入两个链表,找出它们的第一个公共节点。

在这里插入图片描述
在这里插入图片描述

一、思路

1.在这里插入图片描述
2.这是什么绝美的相遇啊(

二、代码

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        a=headA
        b=headB
        while a!=b:
            a=a.next if a else headB
            b=b.next if b else headA
        return a 

【41】礼物的最大价值:在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

在这里插入图片描述

一、思路

1.https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/solution/mian-shi-ti-47-li-wu-de-zui-da-jie-zhi-dong-tai-gu/
2.基础动态规划

二、代码

class Solution(object):
    def maxValue(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        m = len(grid)
        n = len(grid[0])
        for i in range(m):
            for j in range(n):
                if i==0 and j==0:
                    continue
                elif i==0 and j>0:
                    grid[i][j]+=grid[i][j-1]
                elif i>0 and j==0:
                    grid[i][j]+=grid[i-1][j]
                else:
                    grid[i][j]+=max(grid[i][j-1],grid[i-1][j])
        return grid[-1][-1]

【42】丑数:我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

一、思路

1.https://leetcode-cn.com/problems/chou-shu-lcof/solution/mian-shi-ti-49-chou-shu-dong-tai-gui-hua-qing-xi-t/

二、代码

class Solution(object):
    def nthUglyNumber(self, n):
        """
        :type n: int
        :rtype: int
        """
        dp, a, b, c = [1] * n, 0, 0, 0
        for i in range(1, n):
            n2, n3, n5 = dp[a] * 2, dp[b] * 3, dp[c] * 5
            dp[i] = min(n2, n3, n5)
            if dp[i] == n2: a += 1
            if dp[i] == n3: b += 1
            if dp[i] == n5: c += 1
        return dp[-1]

【43】二叉搜索树与双向链表:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

在这里插入图片描述
在这里插入图片描述

一、思路

1.用一个前驱节点一直记录当前节点的前一个值,通过中序遍历来修改左右指针。详细见https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/solution/mian-shi-ti-36-er-cha-sou-suo-shu-yu-shuang-xian-5/

二、代码

class Solution(object):
    def treeToDoublyList(self, root):
        self.pre=None
        self.head=None
        if not root:
            return
        self.new(root)
        self.head.left=self.pre
        self.pre.right=self.head
        return self.head
    def new(self, root):
        if not root:
            return
        self.new(root.left)#递归左子树
        if not self.pre:#记录头节点
            self.head=root
        else:#修改节点指针
            self.pre.right=root#
            root.left=self.pre
        self.pre=root#保存当前节点
        self.new(root.right)#递归右子树

【44】把数组排成最小的数:输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

在这里插入图片描述

一、思路

1.字符串的比较。详细见

二、代码

#解法一:比较简练的版本
class Solution(object):
    def minNumber(self, numbers):
        return "".join(map(str,sorted(numbers, cmp = lambda a, b : cmp(str(a) + str(b), str(b) + str(a)))))
#解法二:比较方便理解
class Solution(object):
    def minNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: str
        """
        if not nums:
            return None
        nums=map(str,nums)#把每一个元素变成字符串
        num=sorted(nums,cmp=self.new)#按照任意两个字符串相加的和的结果最小来排序
        re=''
        for i in num:#最终结果就是排好序的字符串数组,直接按序相加
            re+=i
        return re
    def new(self,str1,str2):#排序的依赖函数
        if str1+str2>str2+str1:
            return 1
        elif str1+str2<str2+str1:
            return -1
        else:
            return 0

【45】在排序数组中查找数字:统计一个数字在排序数组中出现的次数。

在这里插入图片描述

一、思路

1.普通查找。

二、代码

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        if not nums:
            return 0
        if target>nums[-1] or target<nums[0]:
            return 0
        length=len(nums)
        count=0
        for i in range(length):
            if i<=length-2:
                if nums[i]<target<nums[i+1]:
                    return 0
                elif nums[i]==target:
                    count+=1
                elif nums[i]>target:
                    break
            elif i==length-1:
                if nums[i]==target:
                    count+=1
        return count

【46】0-n-1中缺失得数字:一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

在这里插入图片描述

一、思路

1.普通查找。

二、代码

class Solution(object):
    def missingNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return None
        length=len(nums)
        if nums[0]!=0:
            return 0
        for i in range(length):
            if i<=length-2:
                if nums[i+1]-nums[i]==2:
                    return nums[i]+1
        return length

【47】二叉搜索树的第二大节点:给定一棵二叉搜索树,请找出其中第k大的节点。

在这里插入图片描述

一、思路

1.遍历二叉树把每一个节点的值记录下来,再排序输出第k个。
2.中序非递归遍历。

二、代码

思路一:
class Solution(object):
    def kthLargest(self, root, k):
        li=self.list_(root)
        print(li)
        li.sort()
        return li[len(li)-k]
    def list_(self,root):
        li=[]
        re=[]
        li.append(root)
        while li!=[]:
            m=li.pop(0)
            re.append(m.val)
            if m.left:
                li.append(m.left)
            if m.right:
                li.append(m.right)
        return re
思路二:
class Solution(object):
    def kthLargest(self,root,k):
        res=[]
        stack = []
        p = root
        while p or stack:
            while p:
                stack.append(p)
                p = p.left
            p = stack.pop()
            res.append(p.val)
            p = p.right
        return res[len(res)-k]

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

在这里插入图片描述# 一、思路
1.递归求高度。

二、代码

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        left=self.maxDepth(root.left)+1
        right=self.maxDepth(root.right)+1
        if left>=right:
            return left
        else:
            return right

【49】平衡二叉树:输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

一、思路

1.建立在求二叉树高度的基础上,每求一层的高度进行高度差的判断。

二、代码

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def isBalanced(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
        return abs(self.new(root.left)-self.new(root.right))<2 and self.isBalanced(root.left) and self.isBalanced(root.right)
        
    def new(self,root):
        if not root:
            return 0
        return max(self.new(root.left),self.new(root.right))+1

【50】数组中数字出现的次数:一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

一、思路

1.菜鸡的普通想法。
2.大佬思路。

二、代码

#思路一
class Solution(object):
    def singleNumbers(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        temp=[]
        for i in nums:
            if i in temp:
                temp.remove(i)
                continue
            temp.append(i)
            
        return temp
#思路二
class Solution:
    def singleNumbers(self, nums: List[int]) -> List[int]:
        ret = functools.reduce(lambda x, y: x ^ y, nums)
        div = 1
        while div & ret == 0:
            div <<= 1
        a, b = 0, 0
        for n in nums:
            if n & div:
                a ^= n
            else:
                b ^= n
        return [a, b]

【51】数组中数字出现的次数2:在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

一、思路

1.菜鸡的普通想法。

二、代码

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        dic={}
        for i in nums:
            if i not in dic:
                dic[i]=1
            else:
                dic[i]+=1
        for key,value in dic.items():
            if value==1:
                return key

【52】和为s的两个数字:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

一、思路

1.双指针。

二、代码

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        length=len(nums)
        l,r=0,length-1
        while l<r:
            he=nums[l]+nums[r]
            if he==target:
                return [nums[l],nums[r]]
            elif he>target:
                r-=1
            else:
                l+=1
        return []

【53】翻转单词顺序:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。在这里插入图片描述

一、思路

1.普通想法。

二、代码

class Solution(object):
    def reverseWords(self, s):
        """
        :type s: str
        :rtype: str
        """
        re = s.split(" ")
        m = ''
        for i in range(len(re)):
            if re[len(re)-1-i]:
                m+=re[len(re)-1-i]
                m+=' '
        return m[:-1]

【54】和为s的连续正数序列:输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

在这里插入图片描述

一、思路

1.滑动窗口。

二、代码

class Solution(object):
    def findContinuousSequence(self, target):
        """
        :type target: int
        :rtype: List[List[int]]
        """
        i=1
        j=1
        s=0
        re=[]
        while i<=target//2:
            if s<target:
                s+=j
                j+=1
            elif s>target:
                s-=i
                i+=1
            else:
                re.append(list(range(i,j)))
                s-=i
                i+=1
        return re

【55】左旋转字符串:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

在这里插入图片描述

一、思路

1.字符串分割。

二、代码

class Solution(object):
    def reverseLeftWords(self, s, n):
        """
        :type s: str
        :type n: int
        :rtype: str
        """
        s1=s[:n]
        s2=s[n:]
        return s2+s1

【56】队列的最大值:请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。若队列为空,pop_front 和 max_value 需要返回 -1

在这里插入图片描述

一、思路

1.普通思路。

二、代码

class MaxQueue(object):

    def __init__(self):
        self.li=[]

    def max_value(self):
        """
        :rtype: int
        """
        if not self.li:
            return -1
        else:
            return max(self.li)

    def push_back(self, value):
        """
        :type value: int
        :rtype: None
        """
        self.li.append(value)

    def pop_front(self):
        """
        :rtype: int
        """
        if self.li:
            return self.li.pop(0)
        else:
            return -1

# Your MaxQueue object will be instantiated and called as such:
# obj = MaxQueue()
# param_1 = obj.max_value()
# obj.push_back(value)
# param_3 = obj.pop_front()

【57】n个骰子的点数:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。

在这里插入图片描述

一、思路

1.动态规划https://leetcode-cn.com/problems/nge-tou-zi-de-dian-shu-lcof/solution/jian-zhi-offer-60-nge-tou-zi-de-dian-shu-2i2o/

二、代码


class Solution:
    def dicesProbability(self, n: int) -> List[float]:
        '''
            dp[i][j]表示i个骰子,和为j时的概率
            为了保证dp[n]是n个骰子,所以要从把dp长度设置为n+1,即下标从0到n。其中dp[0]无意义,d[i][0]也无意义
            【注意】i个骰子,其和是从i开始的,要到6i,所以范围要用6i+1
        '''
        dp = [ [0]*(6*i+1) for i in range(n+1)]
        p = 1/6

        # i=1时,初始化一个骰子的各种数的可能性,从1到6
        for k in range(1,7):
            dp[1][k] = p

        '''
            i个骰子,和为j:
                i:从2开始,到n
                j:从i开始到6i
        '''
        for i in range(2,n+1):
            for j in range(i,6*i+1):
                dp[i][j] = sum(dp[i-1][max(1,j-6):j])*p
                '''
                当最后一个骰子点数为1时,前i-1个骰子的点数和必须为j-1,概率为1/6;
                当最后一个骰子点数为2时,前n-1个骰子的点数和必须为j-2;
                。。。。。
                以此类推,
                当后一个点数为6,前i-1个骰子的点数和必须为k-6

                和*概率 = 当最后一个骰子点数为1时前i-1个骰子的点数和必须为j-1 * 1/6 + 当最后一个骰子点数为2时前n-1个骰子的点数和必须为j-2 * 1/6 = (最后点数为1 +最后点数为2+....+最后点数为6)* 1/6
                '''
        return dp[n][n:]

【58】扑克牌中的顺子:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。

在这里插入图片描述

一、思路

1.把所有可能的组合遍历出来。
2.不太明白为什么还会有3个,4个0的情况,一副扑克牌只有一个大王一个小王(莫非我从小到大玩的是假扑克?)。
3.题目给的解法中很巧妙,但是不是应该有重复牌的可能性嘛,比如说两个或者多个相同数字的牌,或者是题目要求没说明白题目高赞解法

二、代码

class Solution(object):
    def isStraight(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        nums.sort()
        if 0 not in nums:
            if (nums[0] + 1==nums[1]) and (nums[1]+1==nums[2]) and (nums[2]+1==nums[3]) and (nums[3]+1==nums[4]):
                return True
            else:
                return False
        else:
            c=0
            for i in range(5):
                if nums[i]==0:
                    c+=1
            nums=nums[c:]
            if len(nums)==4:
                if (nums[0]+1==nums[1] and nums[1]+1==nums[2] and nums[2]+1==nums[3]) or (nums[0]+1==nums[1] and nums[1]+2==nums[2] and nums[2]+1==nums[3]) or (nums[0]+2==nums[1] and nums[1]+1==nums[2] and nums[2]+1==nums[3]) or (nums[0]+1==nums[1] and nums[1]+1==nums[2] and nums[2]+2==nums[3]):
                    return True
                else:
                    return False
            elif len(nums)==3:
                if (nums[0]+1==nums[1] and nums[1]+1==nums[2]) or (nums[0]+2==nums[1] and nums[1]+1==nums[2]) or (nums[0]+1==nums[1] and nums[1]+2==nums[2]) or (nums[0]+1==nums[1] and nums[1]+3==nums[2]) or (nums[0]+3==nums[1] and nums[1]+1==nums[2]) or (nums[0]+2==nums[1] and nums[1]+2==nums[2]):
                    return True
                else:
                    return False
            elif len(nums)==2:
                if (nums[0]+1==nums[1]) or (nums[0]+2==nums[1]) or (nums[0]+3==nums[1]) or (nums[0]+4==nums[1]):
                    return True
                else:
                    return False
            elif len(nums)==1 or (not nums):
                return True

【59】股票的最大利润:假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

在这里插入图片描述

一、思路

1.两次循环,求差值最小。(会超时)
2.本质上是求数组中两个数的差值得最小值,用一个值来记录最小的数,每次遇到有更小的值时就更新最小值,再在当前的最大值和当前的差值选出最大的。

二、代码

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices:
            return 0
        minprice=prices[0]
        maxprofit=0
        for i in prices:
            minprice=min(i,minprice)
            maxprofit=max(i-minprice,maxprofit)
        if maxprofit>0:
            return maxprofit
        else:
            return 0

【60】求1+2+…+n:求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

在这里插入图片描述

一、思路

1.不让你用这个,不让你用那个,其实说白了就是让你用递归法?

二、代码

class Solution(object):
    def sumNums(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n==1:
            return 1
        elif n==2:
            return 3
        else:
            return self.sumNums(n-1)+n

【61】不用加减乘除做加法:写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。

一、思路

1.啊,add了。

二、代码

class Solution(object):
    def add(self, a, b):
        """
        :type a: int
        :type b: int
        :rtype: int
        """
        return add(a,b)

【62】二叉搜索树的最近公共祖先:给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

在这里插入图片描述

一、思路

1.是我想不到的https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/solution/mian-shi-ti-68-i-er-cha-sou-suo-shu-de-zui-jin-g-7/

二、代码

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if p.val>q.val:
            p,q=q,p
        while root:
            if q.val<root.val:
                root=root.left
            elif p.val>root.val:
                root=root.right
            else:
                break
        return root

【63】二叉树的最近公共祖先:百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

在这里插入图片描述

一、思路

1.是我想不到的https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/solution/mian-shi-ti-68-ii-er-cha-shu-de-zui-jin-gong-gon-7/

二、代码

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if not root or root==p or root==q:
            return root
        left=self.lowestCommonAncestor(root.left,p,q)
        right=self.lowestCommonAncestor(root.right,p,q)
        if not left and not right:
            return None
        if not right and left:
            return left
        if not left and right:
            return right
        if left and right:
            return root

【64】包含min函数的栈:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

在这里插入图片描述

一、思路

1.普通想法。

二、代码

class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.li=[]

    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        self.li.append(x)

    def pop(self):
        """
        :rtype: None
        """
        if self.li:
            self.li.pop(len(self.li)-1)
    def top(self):
        """
        :rtype: int
        """
        if self.li:
            return self.li[len(self.li)-1]
        else:
            return None
    def min(self):
        """
        :rtype: int
        """
        if self.li:
            return min(self.li)
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.min()

【65】二叉树中和为某一值的路径:输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。

一、思路

1.啊https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/solution/mian-shi-ti-34-er-cha-shu-zhong-he-wei-mou-yi-zh-5/

二、代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def pathSum(self, root: TreeNode, target: int) -> List[List[int]]:
        re=[]
        path=[]
        def recur(root,s):
            if not root:
                return None
            path.append(root.val)
            s-=root.val
            if s==0 and not root.left and not root.right:
                re.append(list(path))
            recur(root.left,s)
            recur(root.right,s)
            path.pop()
        recur(root,target)
        return re

【66】滑动窗口的最大值:给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

在这里插入图片描述

一、思路

1.普通思路。

二、代码

class Solution(object):
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        if not nums:
            return []
        if k==1:
            return nums
        elif k==len(nums):
            return [max(nums)]
        else:
            re=[]
            for i in range(len(nums)-k+1):
                temp=nums[i:i+k]
                re.append(max(temp))
        return re
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值