劍指offer系列(十五)和為S的連續正數序列,和為s的兩個數字,左旋轉字串
和為S的連續正數序列
題目描述
小明很喜歡數學,有一天他在做數學作業時,要求計算出9~16的和,他馬上就寫出了正確答案是100。但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和為100(至少包括兩個數)。沒多久,他就得到另一組連續正數和為100的序列:18,19,20,21,22。現在把問題交給你,你能不能也很快的找出所有和為S的連續正數序列? Good Luck!
輸出描述:
輸出所有和為S的連續正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序
解題思路:
設定兩個指標,先分別指向數字1和數字2,並設這兩個指標為small和big,對small和big求和,如果和大於目標值,
則從當前和中刪除small值,並把small值加一,如果和小於目標值,則把big值加一,再把新的big值加入和中。如果和等於
目標值,就輸出small到big的序列,同時把big加一併加入和中,繼續之前的操作。
舉例看起來更好理解一點,雖然是while迴圈裡面沒有做small到big之間的連線加減,但是由於都是從相鄰出發,加和都是基於
1 2 3相鄰數基礎之上的加和,大了就對第一個數不斷減,小了就對最後一個數不斷加即可。
舉例:輸入 tsum = 5
1 2
middle = 3 cursum = 3
1 < 3:
3 < 5:
1 2 3
cursum = 1 + 2 + 3 = 6
6 > 5:
cursum - small = 6 - 1 = 5
return 2 3
程式碼:
# -*- coding:utf-8 -*- class Solution: def FindContinuousSequence(self, tsum): # write code here if tsum<3: return [] small = 1 big= 2 middle = (tsum+1)//2 cursum = big+small output = [] while small<middle: if cursum == tsum: output.append(list(range(small, big+1))) while cursum > tsum and small <middle: cursum -= small small +=1 if cursum ==tsum: output.append(list(range(small, big+1))) big+=1 cursum += big return output
和為s的兩個數字
題目描述
輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。
輸出描述:
對應每個測試案例,輸出兩個數,小的先輸出。
解題思路:
設定兩個指標,一個指向陣列的起點,一個指向陣列的終點,然後對兩個數字求和,如果和大於目標值,則把後一個指標前移,
如果和小於目標值,則把前一個指標後移。兩個指標交匯的時候如果還沒找到,就終止操作。
程式碼:
# -*- coding:utf-8 -*-
class Solution:
def FindNumbersWithSum(self, array, tsum):
# write code here
if array == None or len(array)<=0 or array[-1]+array[-2]<tsum:
return []
start =0
end = len(array)-1
while start<end:
if array[start]+array[end]<tsum:
start +=1
elif array[start]+array[end]>tsum:
end -=1
else:
return [array[start], array[end]]
return []
左旋轉字串
題目描述
組合語言中有一種移位指令叫做迴圈左移(ROL),現在有個簡單的任務,就是用字串模擬這個指令的運算結果。對於一個給定的字元序列S,請你把其迴圈左移K位後的序列輸出。例如,字元序列S=”abcXYZdef”,要求輸出迴圈左移3位後的結果,即“XYZdefabc”。是不是很簡單?OK,搞定它!
解題思路:
法一:陣列字串的切分
法二:對原字串進行擴充兩倍,在這個基礎上直接從要反轉的地方取就可以,相當於前n個字串翻轉了,思想非常好
法三:首先需要寫一個reverse函式,把任何輸入的字串完全翻轉。然後根據題目中給出的左旋轉字串的個數n,
用全字串長度length減去旋轉字串個數n,求得對於新的字串應該在哪一位進行旋轉,然後分別旋轉前[:length-n]子
串和[length-n:]子串,重新拼接兩個子串即可。
程式碼:
法一:
# -*- coding:utf-8 -*-
class Solution:
def LeftRotateString(self, s, n):
# write code here
return s[n:]+s[:n]
法二:
# -*- coding:utf-8 -*-
class Solution:
def LeftRotateString(self, s, n):
# write code here
if not s:
return ''
length = len(s)
s+=s
return s[n:length+n]
法三:
# -*- coding:utf-8 -*-
class Solution:
def LeftRotateString(self, s, n):
# write code here
if not s or len(s)<n or n<0:
return ''
s = list(s)
length = len(s)
s = self.Reverse(s)
s1 = self.Reverse(s[:length-n])
s2 = self.Reverse(s[length-n:])
result = ''.join(s1)+''.join(s2)
return result
def Reverse(self, s):
start = 0
end = len(s)-1
while start < end:
s[start], s[end]=s[end],s[start]
start +=1
end-=1
return s