剑指offer(jz41--jz50)

jz41 和为S的连续正数序列

描述

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列?

思路

暴力解法:遍历两遍数组,穷举找到所有的序列。
优化解法(滑动窗口):考虑到序列是连续的,可以维护一个两个指针,计算序列值,终止条件是序列的中间数。

代码如下:

def jz41(tsum):
	result=[]
	left=1
	right=1
	temp=0
	while left<=tsum//2:
		if temp<tsum:
			temp+=right
			right+=1
		elif temp>tsum:
			temp-=left
			left+=1
		else:
			result.append([i for i in range(left,right)])
			temp-=left
			left+=1
	return result

jz42 和为S的两个数字

描述

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,返回两个数的乘积最小的,如果无法找出这样的数字,返回一个空数组即可。

思路

保证两个条件:1.这两个数的和为S,利用递增序列的特性,维护两个指针,头部和尾部,一个最大值,一个最小值,计算和,小了,头指针+1,大了,尾指针-1.
2.返回两个乘积最小的,那么就要增加一层,判断乘积。

代码如下:

def jz42(array,tsum):
	result=[0,0]
	left=0
	right=len(array)-1
	maxnum=tsum*tsum
	while left<right:
		if array[left]+array[right]==tsum:
			if array[left]*array[right]<maxnum:
				maxnum=array[left]*array[right]
				result[0]=array[left]
				result[1]=array[right]
				left+=1
				right-=1
			else:
				left+=1
				right-=1
		elif array[left]+array[right]<tsum:
			left+=1
		else:
			right-=1
	if result==[0,0]:
		return []
	return result

jz43 左旋字符串

描述

汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列 S,请你把其循环左移 K 位后的序列输出(保证 K 小于等于 S 的长度)。例如,字符序列S=”abcXYZdef”,要求输出循环左移 3 位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

思路

两个相同的字符串拼接,然后截取子串

代码如下:

def jz43(s,n):
	result=s+s
	i=0
	j=len(s)-1
	return result[i+n:j+n+1]

jz44 反转单词序列

描述

牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“nowcoder. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a nowcoder.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

思路

利用列表,进行字符串划分,再反转拼接

代码如下:

def jz44(s):
	li=s.split(' ')
	li0=li[::-1]
	st=' '.join(li0)
	return st

jz45 扑克牌顺子

描述

现在有2副扑克牌,从扑克牌中随机五张扑克牌,我们需要来判断一下是不是顺子。
有如下规则:

  1. A为1,J为11,Q为12,K为13,A不能视为14
  2. 大、小王为 0,0可以看作任意牌
  3. 如果给出的五张牌能组成顺子(即这五张牌是连续的)就输出true,否则就输出false。
    例如:给出数据[6,0,2,0,4]
    中间的两个0一个看作3,一个看作5 。即:[6,3,2,5,4]
    这样这五张牌在[2,6]区间连续,输出true
    数据保证每组5个数字,每组最多含有4个零,数组的数取值为 [0, 13]

思路

满足两个条件:
1.牌中不能出现一样的数字,这个可以用字典来维护判断。
2.牌中的最大值与最小值差值超不过5,这个需要每次作比较。

代码如下:

def jz45(numbers):
	maxnumber=0
	minnumber=13
	dic={}
	for i in range(len(numbers)):
		if numbers[i]>0:
			if numbers[i] in dic:
				return False
			else:
				dic[numbers[i]]=i
				maxnumber=max(maxnumber,numbers[i])
				minnumber=min(minnumber,numbers[i])
	return maxnumber-minnumber<5

jz46 孩子们的游戏(圆圈中最后剩下的数)

描述

每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

如果没有小朋友,请返回-1

思路

利用单向循环链表,头尾相连,维护一个计数器,当达到删除要求时进行删除操作,并把计数器归零,结束条件是只剩下两个结点时,结束循环。

jz47 求1+2+3+…+n

描述

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

思路

不让用常用的方法,只能用位运算符。但是,使用位运算符还是需要进行递归操作,暂时没有思路。

jz48 不用加减乘除做加法

描述

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

思路

按照位运算符进行加减。& ^

代码如下:

def jz48(num1,num2):
	result=0
	carry=0
	while True:
		result=num1^num2
		carry=(num1&num2)<<1
		num1=result
		num2=carry
		if carry==0:
			break
	return result

jz49 把字符串转换成整数

描述

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
输入描述:
输入一个字符串,包括数字字母符号,可以为空
返回值描述:
如果是合法的数值表达则返回该数字,否则返回0

思路

字符串中还有其他的字母什么的,只要出现,就返回0,而是数字时,就要转换成数字。可以用个字典进行判断输出。

代码如下:

def jz49(s):
	if len(s)==0:
		return 0
	result=0
	dic={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
	if s[0]=='+' or s[0]=='-':
		k=1
	else:
		k=0
	for i in range(k,len(s)):
		if s[i] not in dic:
			return 0
		elif s[i]=='0':
			continue
		else:
			result=result+dic[s[j]]*(10**(len(s)-j-1))
	if s[0]=='-':
		return -result
	else:
		return result

jz50 数组中重复的数字

描述

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任一一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1

思路

维护一个字典进行判断

代码如下:

def  jz50(numbers):
	if len(numbers)==0:
		return -1
	dic={}
	for i in range(len(numbers)):
		if numbers[i] not in numbers:
			dic[numbers[i]]=1
		else:
			dic[numbers[i]]+=1
	for j in range(len(numbers)):
		if dic[numbers[j]]>1:
			return numbers[j]
	return -1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值