目录
31题目:从1到n的整数中1出现的个数
32题目.把数组排成最小的数
33题目:丑数
34题目.第一个只出现一次的字符
35题目:数组中的逆序对
36题目:两个链表的第一个公共结点
37题目:统计一个数字在排序数组中的出现的次数
38题目:二叉树的深度
39题目:平衡二叉树
40题目:数组中只出现一次的数字
比如,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)
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
例如输入数组{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
把只包含质因子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
在一个字符串(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)
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
输入一个数组,求出这个数组中的逆序对的总数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)
输入两个链表,找出它们的第一个公共结点。
思路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
思路:由于是排序数组,可以使用两个指针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)
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,
最长路径的长度为树的深度。
思路:
在二叉树中很多解题的方法都可以用递归来实现,因为左子树和右子树又可以看作一颗二叉树,这种特性
决定了很容易使用递归例如这里求根节点的深度,等于左节点和右节点中的最大深度加一
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
输入一个二叉树,判断是否是平衡二叉树。
平衡二叉树:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过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)
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路:
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)