剑指offer(jz31--jz40) python!!

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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值