日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客网剑指offer编程实践41-50题

發(fā)布時間:2023/12/19 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客网剑指offer编程实践41-50题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

41、和為S的連續(xù)正數(shù)序列

小明很喜歡數(shù)學(xué),有一天他在做數(shù)學(xué)作業(yè)時,要求計(jì)算出9~16的和,他馬上就寫出了正確答案是100。但是他并不滿足于此,他在想究竟有多少種連續(xù)的正數(shù)序列的和為100(至少包括兩個數(shù))。沒多久,他就得到另一組連續(xù)正數(shù)和為100的序列:18,19,20,21,22?,F(xiàn)在把問題交給你,你能不能也很快的找出所有和為S的連續(xù)正數(shù)序列? Good Luck!

解答:

方法1:動態(tài)規(guī)劃

方法2:雙指針技術(shù)

兩個起點(diǎn)相當(dāng)于動態(tài)窗口的兩邊,根據(jù)窗口內(nèi)的值來確定窗口的位置。當(dāng)窗口內(nèi)的值小于S時,右邊窗口向后移動一位;大于S時,左邊窗口向后移動一位

# -*- coding:utf-8 -*- import math class Solution:def FindContinuousSequence(self, tsum):# write code heren = int(math.sqrt(tsum)*2)res_list = []for i in range(2,n+1):if (tsum-i*(i-1)/2) % i == 0:a = (tsum-i*(i-1)/2) / iif a > 0:res_list.append(int(a))res_list = sorted(res_list)result = []for i in res_list:tmp_sum = 0tmp_list = []while tmp_sum != tsum:tmp_sum += itmp_list.append(i)i += 1result.append(tmp_list)return resultdef FindContinuousSequence(self, tsum):begin = 1end = 2res = []while end > begin:if (begin+end)*(end-begin+1)/2 == tsum:tmp_list = []for i in range(begin,end+1):tmp_list.append(i)res.append(tmp_list)begin += 1if (begin+end)*(end-begin+1)/2 < tsum:end += 1if (begin+end)*(end-begin+1)/2 > tsum:begin += 1return res ?

42、和為S的兩個數(shù)字

輸入一個遞增排序的數(shù)組和一個數(shù)字S,在數(shù)組中查找兩個數(shù),使得他們的和正好是S,如果有多對數(shù)字的和等于S,輸出兩個數(shù)的乘積最小的。

解答:

方法:左右夾逼

設(shè)置兩個窗口index,分別為0和len(array)-1,計(jì)算兩個窗口值的和是否為S,若大于S,右邊窗口向前移動一位,小于S左邊窗口向后移動一位;因?yàn)閮蓚€數(shù)的乘積相隔越遠(yuǎn)越小,因此第一個找到的窗口值就是結(jié)果

# -*- coding:utf-8 -*- class Solution:def FindNumbersWithSum(self, array, tsum):# write code herebegin = 0end = len(array) - 1while begin < end:if array[begin] + array[end] == tsum:return array[begin],array[end]if array[begin] + array[end] > tsum:end -= 1if array[begin] + array[end] < tsum:begin += 1return []

43、左旋轉(zhuǎn)字符串

匯編語言中有一種移位指令叫做循環(huán)左移(ROL),現(xiàn)在有個簡單的任務(wù),就是用字符串模擬這個指令的運(yùn)算結(jié)果。對于一個給定的字符序列S,請你把其循環(huán)左移K位后的序列輸出。例如,字符序列S=”abcXYZdef”,要求輸出循環(huán)左移3位后的結(jié)果,即“XYZdefabc”。是不是很簡單?OK,搞定它!

解答:

方法:

n為移動的位數(shù),m為字符串s的長度。s為0時返回‘’;移動位數(shù)k=n%m,然后s = s[:k] + s[k:];

如果不能申請額外的空間,則將s[:k]和s[k:]分別反轉(zhuǎn),然后將整個s反轉(zhuǎn)即所求

# -*- coding:utf-8 -*- class Solution:def LeftRotateString(self, s, n):# write code herem = len(s)if m == 0:return ''if n % m == 0:return sk = n % ms = s[k:] + s[:k]return s

44、翻轉(zhuǎn)單詞順序列

??妥罱鼇砹艘粋€新員工Fish,每天早晨總是會拿著一本英文雜志,寫些句子在本子上。同事Cat對Fish寫的內(nèi)容頗感興趣,有一天他向Fish借來翻看,但卻讀不懂它的意思。例如,“student. a am I”。后來才意識到,這家伙原來把句子單詞的順序翻轉(zhuǎn)了,正確的句子應(yīng)該是“I am a student.”。Cat對一一的翻轉(zhuǎn)這些單詞順序可不在行,你能幫助他么?

解答:

方法1:

將字符串轉(zhuǎn)換成list,翻轉(zhuǎn)list即可

方法2:

首先將字符串翻轉(zhuǎn),然后將每個單詞翻轉(zhuǎn)

# -*- coding:utf-8 -*- class Solution:def ReverseSentence(self, s):# write code heres_list = s.split(' ')s_list = reversed(s_list)return ' '.join(s_list)def ReverseSentence(self, s):s = list(s)begin = 0end = len(s) - 1self.ReversePart(s,begin,end)begin_part = 0end_part = 0while begin_part < len(s) and end_part < len(s):if s[begin_part] == ' ':begin_part += 1end_part += 1elif s[end_part] == ' ':self.ReversePart(s, begin_part, end_part - 1)begin_part = end_part + 1end_part += 1elif end_part + 1 == len(s):self.ReversePart(s, begin_part, end_part)begin_part = end_part + 1end_part += 1else:end_part += 1return ''.join(s) ?def ReversePart(self,s,begin,end):while begin < end:s[begin],s[end] = s[end],s[begin]begin += 1end -= 1

45、 撲克牌順子

LL今天心情特別好,因?yàn)樗ベI了一副撲克牌,發(fā)現(xiàn)里面居然有2個大王,2個小王(一副牌原本是54張^_^)...他隨機(jī)從中抽出了5張牌,想測測自己的手氣,看看能不能抽到順子,如果抽到的話,他決定去買體育彩票,嘿嘿!!“紅心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是順子.....LL不高興了,他想了想,決定大\小 王可以看成任何數(shù)字,并且A看作1,J為11,Q為12,K為13。上面的5張牌就可以變成“1,2,3,4,5”(大小王分別看作2和4),“So Lucky!”。LL決定去買體育彩票啦。 現(xiàn)在,要求你使用這幅牌模擬上面的過程,然后告訴我們LL的運(yùn)氣如何, 如果牌能組成順子就輸出true,否則就輸出false。為了方便起見,你可以認(rèn)為大小王是0。

解答:

方法:

max 記錄 最大值? min 記錄 最小值? min ,max 都不記0? 滿足條件

1、max - min <5

2、沒有重復(fù)的數(shù)字(牌)

3、數(shù)組長度為5

# -*- coding:utf-8 -*- class Solution:def IsContinuous(self, numbers):# write code hereif len(numbers) == 0:return Falsenum = [0] * 14num[0] = -5min_ = 14max_ = -1for i in range(len(numbers)):num[numbers[i]] += 1if num[numbers[i]] > 1:return Falseif numbers[i] == 0:continueif numbers[i] > max_:max_ = numbers[i]if numbers[i] < min_:min_ = numbers[i]if max_ - min_ < 5:return Truereturn False

46、孩子們的游戲(圓圈中最后剩下的數(shù))

每年六一兒童節(jié),??投紩?zhǔn)備一些小禮物去看望孤兒院的小朋友,今年亦是如此。HF作為牛客的資深元老,自然也準(zhǔn)備了一些小游戲。其中,有個游戲是這樣的:首先,讓小朋友們圍成一個大圈。然后,他隨機(jī)指定一個數(shù)m,讓編號為0的小朋友開始報數(shù)。每次喊到m-1的那個小朋友要出列唱首歌,然后可以在禮品箱中任意的挑選禮物,并且不再回到圈中,從他的下一個小朋友開始,繼續(xù)0...m-1報數(shù)....這樣下去....直到剩下最后一個小朋友,可以不用表演,并且拿到??兔F的“名偵探柯南”典藏版(名額有限哦!!^_^)。請你試著想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)

解答:

方法:約瑟夫問題

把n個人的編號改為0~n-1,然后對刪除的過程進(jìn)行分析。

第一個刪除的數(shù)字是(m-1)%n,幾位k,則剩余的編號為(0,1,...,k-1,k+1,...,n-1),下次開始刪除時,順序?yàn)?k+1,...,n-1,0,1,...k-1)。

用f(n,m)表示從(0~n-1)開始刪除后的最終結(jié)果。

用q(n-1,m)表示從(k+1,...,n-1,0,1,...k-1)開始刪除后的最終結(jié)果。

則f(n,m)=q(n-1,m)。

下面把(k+1,...,n-1,0,1,...k-1)轉(zhuǎn)換為(0~n-2)的形式,即

k+1對應(yīng)0

k+2對于1

...

k-1對應(yīng)n-2

轉(zhuǎn)化函數(shù)設(shè)為p(x)=(x-k-1)%n, p(x)的你函數(shù)為p^(x)=(x+k+1)%n。

則f(n,m)=q(n-1,m)=p^(f(n-1,m))=(f(n-1,m)+k+1)%n,又因?yàn)閗=(m-1)%n。

f(n,m)=(f(n-1,m)+m)%n;

最終的遞推關(guān)系式為

f(1,m) = 0; (n=1)

f(n,m)=(f(n-1,m)+m)%n; (n>1)

# -*- coding:utf-8 -*- class Solution:def LastRemaining_Solution(self, n, m):# write code hereif n == 0 or m == 0:return -1if n == 1:return 0res = 0for i in range(2,n+1):res = (res + m) % ireturn res

47、求1+2+3+...+n

求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關(guān)鍵字及條件判斷語句(A?B:C)。

解答:

方法:

1.需利用邏輯與的短路特性實(shí)現(xiàn)遞歸終止。

2.當(dāng)n==0時,(n>0)&&((sum+=Sum_Solution(n-1))>0)只執(zhí)行前面的判斷,為false,然后直接返回0;

3.當(dāng)n>0時,執(zhí)行sum+=Sum_Solution(n-1),實(shí)現(xiàn)遞歸計(jì)算Sum_Solution(n)。

# -*- coding:utf-8 -*- class Solution:def Sum_Solution(self, n):# write code herereturn n and (n +self.Sum_Solution(n-1))

48、不用加減乘除做加法

寫一個函數(shù),求兩個整數(shù)之和,要求在函數(shù)體內(nèi)不得使用+、-、*、/四則運(yùn)算符號。

解答:

方法:使用位運(yùn)算

兩個數(shù)相加可以看成兩個數(shù)的每個位先相加,但不進(jìn)位,然后在加上進(jìn)位的數(shù)值

如12+8可以看成二進(jìn)制中可以表示為1000+1100 先每個位置相加不進(jìn)位,

異或結(jié)果:0100,出現(xiàn)進(jìn)位,將與運(yùn)算結(jié)果左移一位,(1000 & 1100) << 1 = 1 0000

最后將上面兩步的結(jié)果相加,相加的時候依然要考慮進(jìn)位的情況,直到不產(chǎn)生進(jìn)位

注意python沒有無符號右移操作,所以需要越界檢查

按位與運(yùn)算:相同位的兩個數(shù)字都為1,則為1;若有一個不為1,則為0。

按位異或運(yùn)算:相同位不同則為1,相同則為0。

# -*- coding:utf-8 -*- class Solution:def Add(self, num1, num2):# write code herewhile num2:result = (num1 ^ num2) & 0xffffffffcarry = ((num1 & num2) << 1) & 0xffffffffnum1 = resultnum2 = carryif num1 <= 0x7fffffff:result = num1else:result = ~(num1^0xffffffff)return result

1、越界檢查

& 0xFFFFFFFF 操作,其中 & 是按位與, 0xFFFFFFFF代表16進(jìn)制下的邊界 (按二進(jìn)制表示的話,對應(yīng)4*8=32位)。

由于python長整數(shù)類型可以表示無限位,所以需要人為設(shè)置邊界,避免死循環(huán)。

設(shè)置成32位應(yīng)該是考慮到其他語言的特點(diǎn),測試樣例中不會出現(xiàn)超過32位整型的數(shù),實(shí)際上,把邊界調(diào)大的話,不會影響最終結(jié)果

2、~(num1^0xffffffff)

負(fù)數(shù)取反操作

3、不使用新變量,交換兩個變量的值

49、 把字符串轉(zhuǎn)換成整數(shù)

將一個字符串轉(zhuǎn)換成一個整數(shù)(實(shí)現(xiàn)Integer.valueOf(string)的功能,但是string不符合數(shù)字要求時返回0),要求不能使用字符串轉(zhuǎn)換整數(shù)的庫函數(shù)。 數(shù)值為0或者字符串不是一個合法的數(shù)值則返回0。

解答:

方法:

1、設(shè)置一個Invalid參數(shù),因?yàn)樽址敵?和無效輸入需要區(qū)分

2、只計(jì)算整數(shù),則每個字符s[i],if s[i] < '0' or s[i] > '9' 則直接返回0,Invalid = True

3、輸入的字符串為空,同樣輸出0,Invalid = True

4、正整數(shù)最大為 0x7FFFFFFF,負(fù)整數(shù)最小為0x80000000,注意負(fù)整數(shù)這里是res >0x80000000時輸入無效

# -*- coding:utf-8 -*- class Solution:def StrToInt(self, s):# write code hereInvalid = Falseif not s:Invalid = Truereturn 0minus = 1begin = 0if s[0] == '+':begin = 1if s[0] == '-':begin = 1minus = -1res = 0for i in range(begin,len(s)):if s[i] < '0' or s[i] > '9':Invalid = Truereturn 0res = res * 10 + minus * (int(s[i]) & 0xF)if ((minus == 1) and res > 0x7FFFFFFF) or ((minus == -1) and res > 0x80000000):Invalid = Truereturn 0return res ?

50、數(shù)組中重復(fù)的數(shù)字

在一個長度為n的數(shù)組里的所有數(shù)字都在0到n-1的范圍內(nèi)。 數(shù)組中某些數(shù)字是重復(fù)的,但不知道有幾個數(shù)字是重復(fù)的。也不知道每個數(shù)字重復(fù)幾次。請找出數(shù)組中任意一個重復(fù)的數(shù)字。 例如,如果輸入長度為7的數(shù)組{2,3,1,0,2,5,3},那么對應(yīng)的輸出是第一個重復(fù)的數(shù)字2。

解答:

方法1:利用輔助空間dict,時間復(fù)雜度O(n),空間復(fù)雜度O(n)

方法2:將每一個數(shù)字放在對應(yīng)的位置,即numbers[i] = i

1、如果numbers[i] != i時,index = numbers[i],交換number[i]和numbers[index],注意這里不能直接使用swap或python交換公式,需要一步步進(jìn)行

2、當(dāng)遇到numbers[i] == numbers[index]時,就終止循環(huán),找到了這個重復(fù)的值為numbers[i],

3、因?yàn)槊總€數(shù)字最多交換兩次就可以找到對應(yīng)的位置,總時間復(fù)雜度為O(n),空間復(fù)雜度為O(1)

方法3:

當(dāng)一個數(shù)字被訪問過后,可以設(shè)置對應(yīng)位上的數(shù) + n,之后再遇到相同的數(shù)時,會發(fā)現(xiàn)對應(yīng)位上的數(shù)已經(jīng)大于等于n了,那么直接返回這個數(shù)即可。

注意:這種+len(numbers)的方式可能會溢出,時間復(fù)雜度O(n),空間復(fù)雜度O(1)

# -*- coding:utf-8 -*- class Solution:# 這里要特別注意~找到任意重復(fù)的一個值并賦值到duplication[0]# 函數(shù)返回True/Falsedef duplicate(self, numbers, duplication):numbers_dict = {}if not numbers:return Falsefor i in numbers:if i < 0 or i >= len(numbers):return Falseif i not in numbers_dict:numbers_dict[i] = 0numbers_dict[i] += 1if numbers_dict[i] == 2:duplication[0] = ireturn Truereturn False ?def duplicate(self, numbers, duplication):if not numbers:return Falsefor i in range(len(numbers)):if numbers[i] < 0 or numbers[i] >= len(numbers):return Falsewhile numbers[i] != i:if numbers[i] == numbers[numbers[i]]:duplication[0] = numbers[i]return Truetmp = numbers[i]numbers[i] = numbers[tmp]numbers[tmp] = tmpreturn False ?def duplicate(self, numbers, duplication):if not numbers:return Falsefor i in range(len(numbers)):if numbers[i] < 0:return Falseindex = numbers[i]if index >= len(numbers):index -= len(numbers)if numbers[index] >= len(numbers):duplication[0] = indexreturn Truenumbers[index] += len(numbers)return False

總結(jié)

以上是生活随笔為你收集整理的牛客网剑指offer编程实践41-50题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。