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副扑克牌,从扑克牌中随机五张扑克牌,我们需要来判断一下是不是顺子。
有如下规则:
- A为1,J为11,Q为12,K为13,A不能视为14
- 大、小王为 0,0可以看作任意牌
- 如果给出的五张牌能组成顺子(即这五张牌是连续的)就输出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