剑指offer-题目-思路-python实现31-40

目录

31题目:从1到n的整数中1出现的个数

32题目.把数组排成最小的数

33题目:丑数

34题目.第一个只出现一次的字符

35题目:数组中的逆序对

36题目:两个链表的第一个公共结点

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

38题目:二叉树的深度

39题目:平衡二叉树

40题目:数组中只出现一次的数字


31题目:从1到n的整数中1出现的个数

比如,1-16中,1出现9次,分别是1,10,11,12,13,14,15,16。
思路:1-n个数中,循环除以10,余数为1,则count+=1;

class Solution:
    def numOf1(self,n):
        num=0
        for i in range(1,n+1):
            while i>0:
                if i%10==1:
                    num+=1
                i=int(i/10)
        return num

s=Solution()
r=s.numOf1(16)
print(r)

32题目.把数组排成最小的数

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

思路:

1、将数组转化为字符串,进行拼接,

2、比较s1+s2,和s2+s1那个大,如果s1+s2大,那说明s2应该放前面,所以按这个规则,s2就应该排在s1前面。

py3中要调用该关键字必须要import functools库里面的cmp_to_key

from functools import cmp_to_key
class Solution:
    def PrintMinNumber(self, a):
        def cmp_xy(x,y):
            if x+y>y+x:
                return 1
            elif x+y

33题目:丑数

把只包含质因子2、3和5的数称作丑数。例如6、8都是丑数,但14不是,因为它包含质因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

思路1:判断丑数,循环直到找到第N个

思路2:时间换空间,丑数只可能由2,3,5这些因子组成,在丑数列表中乘以2,3,5,并每次取最小值
                1)ugly=[1],1直接放入到数组,
                2)维持2,3,5,三个索引,初始化为0;
                3)找到当前数组中的最小数min_num;
                4)取当前数组中的数,分别乘2 或乘3,或乘5,直到大于min_num;并将三个中的最小数,添加到结果列表

class Solution:
    def isUglyNum(self,m):
        while(m%2==0):
            m=m/2
        while(m%3==0):
            m=m/3
        while(m%5==0):
            m=m/5
        if(m==1):
            return True
        return False
    
    def uglyNum1(self,n):
        if n==0:
            return 0
        uglyIndex=0
        num=0
        while(uglyIndex

34题目.第一个只出现一次的字符

在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它
的位置, 如果没有则返回 -1(需要区分大小写)。

思路:因有256个字符,创建长度为256的哈希表。ord(c),c为字符,返回字符对应的整数

class Solution:
    def firstNotRepeatChar(self,s):
        hs=[0]*256
        for i in s:
            hs[ord(i)]+=1
            
        index=-1
        for i in s:
            if hs[ord(i)]==1:
                index=s.index(i)
                return index
        return index


s=Solution()
r=s.firstNotRepeatChar("asdfghjkklasrch")
print(r)

35题目:数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

思路:复制一个数组,对其排序,取最小值,判断其在原始数组中的位置,此位置即为该元素存在的逆序对,
当前最小值的逆序对已经计算过,与其后元素不构成逆序对,计算下一个值时,去掉已计算过的最小数

def inverse_pairs(a):
    b=sorted(a)
    inv_cnt=0
    for i in b:
        pos=a.index(i)
        inv_cnt+=pos
        a.pop(pos)
    #print(inv_cnt)
    res=inv_cnt%1000000007
    return res

a=[2,3,1,4,5,0]
r=inverse_pairs(a)
print(r)

36题目:两个链表的第一个公共结点

输入两个链表,找出它们的第一个公共结点。
思路1
设置两个指针,一个从h1开始遍历,遍历完h1再遍历h2,另一个从h2开始遍历,
遍历完h2再遍历h1,如果有交点,两个指针会同时遍历到交点处。

思路2
对于两个链表,如果有公共节点,则第一个公共节点后面的节点都是公共的;
1、计算两个链表的长度,比较两长度的大小
2、设置两指针,将指针指向较长指针的先先前走len1-len2步
3、两指针分别遍历h1,h2,两指针相等时,返回

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

class Solution:
    def find_first_common_node1(self,h1,h2):
        p1=h1
        p2=h2
        while p1!=p2:
            if p1 is None:
                p1=h2
            else:
                p1=p1.next

            if p2 is None:
                p2=h1
            else:
                p2=p2.next
        return p1
    
    def find_first_common_node2(self,h1,h2):
        len1=0
        len2=0
        
        p1=h1
        p2=h2
        
        while(p1):
            len1+=1
            p1=p1.next
        
        while(p2):
            len2+=1
            p2=p2.next
        
        p1=h1
        p2=h2
            
        if len1

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

思路:由于是排序数组,可以使用两个指针p1,p2二分查找

class Solution:
    def getNumOfK(self,a,k):
        if(len(a)==0):
            return 0
        
        s=0
        e=len(a)-1
        
        while sk:
                e-=1
        if a[s]!=k:
            return 0
        return (e-s)+1

a=[1,2,3,3,3,4,5,6,6,7,8]

s=Solution()
r=s.getNumOfK(a,6)
print(r)

38题目:二叉树的深度

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,
最长路径的长度为树的深度。
思路:
在二叉树中很多解题的方法都可以用递归来实现,因为左子树和右子树又可以看作一颗二叉树,这种特性
决定了很容易使用递归例如这里求根节点的深度,等于左节点和右节点中的最大深度加一

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

class Solution:
    def treeDeep(root):
        if root is None:
            return 0
        return max(treeDeep(root.left),treeDeep(root.right))+1

39题目:平衡二叉树

输入一个二叉树,判断是否是平衡二叉树。
平衡二叉树:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

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

class Solution:
    def treeDeep(self,root):
        if root is None:
            return 0
        return max(treeDeep(root.left),treeDeep(root.right))+1
    
    def isBalance(self,root):
        if root is None:
            return True
        
        if abs(treeDeep(self,root.left)-treeDeep(root.right))<1:
            return True
        
        return self.isBalance(root.left) and self.isBalance(root.right)

40题目:数组中只出现一次的数字

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

思路:
1、两个相同的数异或结果为0,对数组中的数进行一遍异或操作,最终得到两个不同数的异或结果r1;
2、异或结果中出现的第一个1即为两个数的不同位,通过这个不同位可以将原始数组分成两部分;
3、两个数组分别做异或操作,得到不同的两个数

class Solution:
    def findDiffNum(self,a):
        t,mask,num1,num2=0,1,0,0
        
        #数组进行异或操作
        for i in a:
            t^=i
        print(t)
        #找到不同的数的最右不同位1
        while t&1==0:
            t=t>>1
            mask=mask<<1
            
        print(mask)
        for i in a:
            if i&mask==0:
                num1^=i
            if i&mask!=0:
                num2^=i
        return num1,num2


a=[1,2,3,4,5,6,1,3,4,5,6,7]

s=Solution()
r=s.findDiffNum(a)
print(r)

 

你可能感兴趣的:(编程题汇总)