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]<min:
min=prices[i]
if max<0:
return 0
return max
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