1.数值的整数次方。(剑指offer16题)
实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
思路:考虑指数为整数,负数,0的三种情况。数值的负数次幂 为取幂的绝对值 然后取结果的倒数。 n为偶数时:a^n=a^(n/2)*a^(n/2) n为奇数时:a^n=a^(n-1/2)*a^(n-1/2)*a
def myPow(x , n):
#指数大于等于0的情况
if n>=0:
if n==0:
return 1
if n==1:
return x
res=myPow(x, n//2)
res=res*res
if n%2==1:
res=res*x
return res
#指数小于0的情况
else:
t=-n
if t==1:
return 1/x
res = self.myPow(x, t//2)
res*=res
if t%2==1:
res*=x
return 1/res
2.数字序列中某一位的数字(剑指offer第44题)
数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。请写一个函数,求任意第n位对应的数字。
思路:1位数10个,占位10;二位数90个,占位180(每个数字占位2);三位数900个,占位3*900; 首先判断目前位数在几位数的区间,然后减去前面前面所有位数所占的空间。得到该数在所在位数区间里的位置,计算它与位数的整除值,及余数。 整除值可以得到该位所在的数字,余数可以得到它在所在数字的具体位置。
def findNthDigit(n):
if n<10:
return n
#计算所在区间的位数 也就是搞清楚它是几位数
i=1
flag=1
sum=10
while n>=sum:
i=i*10
flag+=1
sum+=9*i*flag
n=n-(sum-9*i*flag-1)
#求整除值和余数
k1=n%flag
k2=n//flag
#假如余数为0,说明刚好是这个数字最后一位
if k1==0:
now=k2+pow(10,flag-1)-1
s=str(now)
return int(s[-1])
#假如余数不为0,说明它在下一个数字的余数-1位
else:
now=k2+pow(10,flag-1)-1+1
s=str(now)
return int(s[k1-1])
3.把数字翻译成字符串(剑指offer第46题)
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
思路:每次可以选1个数字翻译或者两个数字翻译,选择两个数字翻译需要判断这个数字在10到26之间则满足要求。 遍历之后则继续递归遍历接下来的数字,最终数字只剩1则返回1,最终数字只剩2,如果可以翻译则sum+1,再加上遍历1个1个的情况。
def translateNum(num):
sum=0
s=str(num)
if len(s)==1:
return 1
if len(s)==0:
return 0
if int(s[0:2])>=10 and int(s[0:2])<26:
if len(s)==2:
sum+=1
else:
sum+=self.translateNum(int(s[2:]))
sum+=self.translateNum(int(s[1:]))
return sum
4.在排序数组中查找数字 (剑指offer53题1)
统计一个数字在排序数组中出现的次数。
def search(nums, target) :
#如果是空数组,直接返回0
if len(nums)==0:
return 0
i=0
#找到这个数字第一次出现的位置
while nums[i]!=target:
i=i+1
if i==len(nums):
break
#找到最后也没找到,则返回0
if i==len(nums):
return 0
flag=i
#继续从该数字开始出现的位置找,直到下一个不一样的数字出现,
while nums[i]==target:
i=i+1
if i==len(nums):
break
return i-flag
5.0~n-1中缺失的数字(剑指offer53题2)
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
def missingNumber(nums):
#如果长度为1,数组值为1,返回0;数组值为0,返回1.
if len(nums)==1 and nums[0]==0:
return 1
if len(nums)==1 and nums[0]==1:
return 0
#寻找i下标对应的位置不是i的那个数,即为缺失值
flag=0
for i in range(len(nums)):
if nums[i]!=i:
flag=i
break
#没有符合的情况,即为[1,2] [1,2,3]这种情况,返回数组的下一个数字。
if i==len(nums)-1 and flag==0:
return len(nums)
return flag
6.股票的最大利润(剑指offer63题)
思路:用一个变量min记录位置i之前的最小值;那么遍历一遍数组,i位置的数字减去它之前的最小值,如果比目前最大的利润大则将当前利润替换为最大值。 判断1:最大值小于0,无符合要求 返回0; 判断2:输入列表长度小于2,返回0
def maxProfit(prices):
if len(prices)<2:
return 0
max=prices[1]-prices[0]
min=prices[0]
for i in range(1,len(prices)):
if prices[i]-min>max:
max=prices[i]-min
if prices[i]
7.扑克牌中的顺子(剑指offer61题)
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A不能视为14。
思路:排序,然后统计0出现的次数,以及 剩余其他数字相邻之间的差值和,如果相邻元素差比1大,则将差值减1的值加到和中,最终只要0出现的次数大于需要弥补的差值总和即可判定为顺子。 需要注意:出现对子的情况直接判定为不能。
def isStraight(nums]):
nums.sort()
#统计0出现的次数
count_0 = 0
for i in range(len(nums)):
if nums[i]==0:
count_0+=1
#统计相邻元素的差值总和
sum=0
for i in range(count_0,len(nums)-1):
#出现对子判定为不是顺子
if nums[i+1]-nums[i]==0:
return False
if nums[i+1]-nums[i]!=1:
sum+=nums[i+1]-nums[i]-1
#0的个数大于相邻元素差值和即可判定是顺子。
if count_0>=sum:
return True
else:
return False