剑指0ffer—67道在线编程—jz41~jz50
jz41 和为S的连续正数序列
题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
- 【输出描述】
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
思路分析:
左右指针移动法:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|
↑ ↑ \uparrow \quad \quad \uparrow ↑↑
1,定义两个指针,左指针从1开始,右指针从2开始循环开始
2,左右指针区间求和
3,如果和小于给定数,右指针++,
4,如果和大于20,左指针++,
5,如果和等于给定值,得一解,添加到列表中,左右指针各加一,重复进行2,3,4
循环结束条件:左指针走到给定数的一半即可终止,因为题目要求至少包含2个数。
【代码实现】
# -*- coding:utf-8 -*-
class Solution:
def FindContinuousSequence(self, tsum):
i,j,lists=1,2,[]
while j<=(tsum+1)//2:#走到sum的一半即可终止,因为题目要求至少包含2个数
t=sum(range(i,j+1))
if t<tsum:#如果和小于给定总数,则右指针加一,长度变大
j+=1
elif t>tsum:#如果和大于给定总数,则左指针加一,长度变小
i+=1
else:#如果相等,则满足条件,为解
lists.append(range(i,j+1))
i+=1
j+=1
return lists
jz42 和为S的两个数字
题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
- 【输出描述】
对应每个测试案例,输出两个数,小的先输出。
思路分析:
双指针法
因为数组是有序的,所以可以用双指针,指向数组的首尾,具体步骤如下:
1.初始化:指针i指向数组首, 指针j指向数组尾部
2. 如果arr[i] + arr[j] == sum , 说明是可能解
3. 否则如果arr[i] + arr[j] > sum, 说明和太大,所以j-=1
4. 否则如果arr[i] + arr[j] < sum, 说明和太小,所以i+=1
另外,如果有多对数字的和为s,可以用数学证明一个最小的数和最大的数的乘积是最小的,比如1,3和2,2。所以输出的时候我们只用考虑找到第一个最小的数就行了,不用担心排序的问题。
【代码实现】
# -*- coding:utf-8 -*-
class Solution:
def FindNumbersWithSum(self, array, tsum):
if not array:
return []
i=0
j=len(array)-1
while(True):#无限循环
if i==j:
return []
if array[i]+array[j]==tsum:
return [array[i],array[j]]
elif array[i]+array[j]>tsum:
j-=1
else:
i+=1
jz43 左旋转字符串
题目描述
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
【代码实现】
# -*- coding:utf-8 -*-
class Solution:
def LeftRotateString(self, s, n):
# write code here
return s[n:]+s[:n]
jz44 翻转单词序列
题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
【代码实现】
# -*- coding:utf-8 -*-
class Solution:
def ReverseSentence(self, s):
# write code here
lists=s.split(' ')#分离句子
return ' '.join(lists[::-1])#返回倒序的原list
jz45 扑克牌顺子
题目描述
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。
思路分析:
【代码实现】
jz46 孩子们的游戏(圆圈中最后剩下的数)
题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)
如果没有小朋友,请返回-1
题目链接
思路分析:
【代码实现】
jz47 求前n项和
题目描述
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
思路分析:
递归求和
【代码实现】
# -*- coding:utf-8 -*-
class Solution:
def Sum_Solution(self, n):
if n==1:
return 1
else:
return self.Sum_Solution(n-1)+n
jz48 不用加减乘除做加法
题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
【代码实现】
# -*- coding:utf-8 -*-
class Solution:
def Add(self, num1, num2):
# write code here
s=[]
s.append(num1)
s.append(num2)
return sum(s)
jz49 把字符串转换成整数
题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
- 输入描述:
输入一个字符串,包括数字字母符号,可以为空
- 输出描述:
如果是合法的数值表达则返回该数字,否则返回0
- 实例一
- 输入
+2147483647
1a33
- 输出
2147483647
0
题目链接
思路分析:
1、先作为整体进行判断,排除异常字符串
2、只要有非法字符,就返回0
【代码实现】
# -*- coding:utf-8 -*-
class Solution:
def StrToInt(self, s):
if s in ['','-','+','+-','-+']:
return 0
count=0
for i in s:
if i not in '0123456789+-':
count+=1
for i in s[1:]:
if i not in '0123456789':
count+=1
if count:
return 0
return int(s)
jz50 数组中重复的数字
题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思路分析:
因数组中肯定有重复数组,故最后一个不用再判定是否相等。
【代码实现】
# -*- coding:utf-8 -*-
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
def duplicate(self, numbers, duplication):
for i in range(len(numbers)-1):
for j in range(i+1,len(numbers)):
if numbers[i]==numbers[j]:
duplication[0]=numbers[i]
return True
return False