jz31 整数中1出现的次数(从1到n整数中1出现的次数)
描述
输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数
例如,1~13中包含1的数字有1、10、11、12、13因此共出现6次
思路
直接方法:把1-n个数字拼接成一个字符串,遍历出1的个数,最简单直接的方法。时间复杂度接近于kn。基本可行
代码如下:
def jz31(s):
count=0
t=''
for i in range(len(s)):
t+=str(i)
for j in t:
if j=='1':
count+=1
return count
jz32 把数组排成最小的数
描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路
自己的思路:先是数组进行排序,再根据字符串比较大小,最后输出最小的数字。
代码如下:
def jz32(numbers):
if numbers=[]:
return ''
numbers.sort()
for i in range(len(numbers)-1):
numbers[0]=minnumber(str(numbers[0]),str(numbers[0]))
numbers.pop(1)
return numbers[0]
def minnumber(a,b):
if a+b<b+a:
return a+b
else:
return b+a
jz33 丑数
描述
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路
设置三个指针,分别代表在数组位置上可以相乘2或3或5,每次比较一下,选出最小的数。
代码如下:
def jz33(n):
if n<=0:
retunr 0
result=[0 for _ in range(n)]
result[0]=1
a=0
b=0
c=0
for i in range(1,n):
result[i]=min(result[a]*2,min(result[b]*3,result[c]*5))
if result[i]==result[a]*2:
a+=1
if result[i]==result[b]*3:
b+=1
if result[i]==result[c]*5:
c+=1
return result[n-1]
jz34 第一次只出现一次的字符
描述
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)
思路
利用字典存储出现的次数,然后遍历字符串,看出现一次的字符
代码如下:
def jz34(s):
if len(s)<=0:
return -1
dic={}
for i in range(len(s)):
if s[i] not in dic:
dic[s[i]]=1
else:
dic[s[i]]+=1
for j in range(len(s)):
if dic[s[j]] ==1:
return j
return -1
jz35 数组中的逆序对
描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
对于50%50%50%的数据,size≤104size\leq 10^4size≤104
对于100%100%100%的数据,size≤105size\leq 10^5size≤105
思路
暴力解法:循环遍历两边,找出逆序对数。
简单解法:用归并排序????暂时不能理解
jz36 两个链表的第一个公共结点
描述
输入两个无环的单链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
思路
关键在于怎么让两个链表变成一样长度的?可以进行链表拼接,用两个指针进行判断。
代码如下:
def jz36(head1,head2):
if not head1:
return None
if not head2:
return None
pre=head1
later=head2
while pre!=later:
pre=pre.next
later=later.next
if pre!=later:
if not pre:
pre=head2
if not later:
later=head1
return pre
jz37 数字在升序数组中出现的次数
描述
统计一个数字在升序数组中出现的次数。
思路
暴力解法:直接遍历一遍数组,输出
二分解法:确定上下界,但不太好确定,则二分法找到一个目标值,进行前后查找
代码如下:
def jz37(data,k):
left=0
right=len(data)-1
flag=0
while left<right:
mid=(left+right)//2
if data[mid]<k:
left=mid
elif data[mid]>k:
right=mid
else:
flag=mid
pre=flag-1
later=flag+1
count=1
while pre>=0:
if data[pre]==k:
count+=1
pre-=1
while later<=len(data)-1:
if data[later]==k:
count+=1
later+=1
return count
jz38 二叉树的深度
描述
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
思路
递归获取树的深度
代码如下:
def jz38(root):
if not root:
return 0
left=jz38(root.left)
right=jz38(root.right)
return max(left,right)+1
jz39 平衡二叉树
描述
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树
平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
注:我们约定空树是平衡二叉树。
思路
根据上一题的深度求解,这一次循环递归,判断深度是否合理
代码如下:
def jz39(root):
if not root:
return True
if abs(jz38(root.left)-jz38(root.right))>1:
return False
return jz39(root.left) and jz39(root.right)
def jz38(root):
if not root:
return 0
left=jz38(root.left)
right=jz38(root.right)
return max(left,right)+1
jz40 数组中只出现一次的两个数
描述
一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路
字典遍历,循环找出,排序
代码如下:
def jz40(numbers):
dic={}
li=[]
for i in range(len(numbers)):
if numbers[i] not in dic:
dic[numbers[i]]=1
else:
dic[numbers[i]]+=1
for j in numbers:
if dic[j]==1:
li.append(j)
if li[0]>li[1]:
temp=li[0]
li[0]=li[1]
li[1]=temp
return li