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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客网剑指offer编程实践21-30题

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

21、棧的壓入、彈出序列

輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否可能為該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)

解答:

# 【思路】借用一個輔助的棧,遍歷壓棧順序,先講第一個放入棧中,這里是1,然后判斷棧頂元素是不是出棧順序的第一個元素,

# 這里是4,很顯然1≠4,所以我們繼續壓棧,直到相等以后開始出棧,出棧一個元素,則將出棧順序向后移動一位,直到不相等,

# 這樣循環等壓棧順序遍歷完成,如果輔助棧還不為空,說明彈出序列不是該棧的彈出順序。

# 舉例:

# 入棧1,2,3,4,5

# 出棧4,5,3,2,1

# 首先1入輔助棧,此時棧頂1≠4,繼續入棧2

# 此時棧頂2≠4,繼續入棧3

# 此時棧頂3≠4,繼續入棧4

# 此時棧頂4=4,出棧4,彈出序列向后一位,此時為5,,輔助棧里面是1,2,3

# 此時棧頂3≠5,繼續入棧5

# 此時棧頂5=5,出棧5,彈出序列向后一位,此時為3,,輔助棧里面是1,2,3

# ….

# 依次執行,最后輔助棧為空。如果不為空說明彈出序列不是該棧的彈出順序

class Solution:def IsPopOrder(self, pushV, popV):stack = []if len(pushV) != len(popV):return Falsefor i in range(len(pushV)):stack.append(pushV[i])while len(stack)>0 and stack[-1] == popV[0]:stack.pop()popV.pop(0)if len(popV):return Falsereturn True

22、從上往下打印二叉樹

從上往下打印出二叉樹的每個節點,同層節點從左至右打印。

解答:

方法:實際就是廣度優先遍歷,二叉樹的層次遍歷。利用一個輔助隊列,首先將根節點壓入隊列,然后彈出隊列,將根節點值append到result,然后將根節點的左右子樹分別壓入隊列。

# -*- coding:utf-8 -*- # class TreeNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.left = None # ? ? ? ? self.right = None class Solution:# 返回從上到下每個節點值列表,例:[1,2,3]def PrintFromTopToBottom(self, root):# write code hereif not root:return []stack = []res = []stack.append(root)while stack:node = stack.pop(0)res.append(node.val)if node.left:stack.append(node.left)if node.right:stack.append(node.right)return res

23、 二叉搜索樹的后序遍歷序列

輸入一個整數數組,判斷該數組是不是某二叉搜索樹的后序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。

解答:

方法1:遞歸方法。

二叉搜索樹,左子樹不大于根節點,右子樹不小于根節點。后序遍歷序列,則sequence[-1]為根節點,遍歷序列找到的第一個大于根節點的數就是右子樹的開始,前面的數都是左子樹。注意判斷右子樹中有沒有小于根節點的數,若存在返回False。然后判斷左右子樹是否存在,存在則遞歸判斷。最后返回左右子樹標記的與結果。

注意,序列長為0放回False,序列長為1返回True

方法2:非遞歸方法。

類似遞歸的思想,遍歷序列判斷出第一個大于根節點的數,由于左子樹一定小于右子樹,可以將左子樹看做右子樹的左子樹,直接判斷右子樹是否符合要求即可

# -*- coding:utf-8 -*- class Solution:def VerifySquenceOfBST(self, sequence):# write code hereif not sequence:return Falseif len(sequence) == 1:return Trueroot = sequence[-1]k = 0for i in range(len(sequence)):if sequence[i] >= root:k = ibreakfor i in range(k, len(sequence) - 1):if sequence[i] < root:return Falseleft = sequence[:k]right = sequence[k:-2]left_tag = Trueright_tag = Trueif left:left_tag = self.VerifySquenceOfBST(left)if right:right_tag = self.VerifySquenceOfBST(right)return left_tag and right_tag ?def VerifySquenceOfBST(self, sequence):# write code hereif not sequence:return Falseif len(sequence) == 1:return Truei = 0n = len(sequence)while n:while sequence[i] < sequence[n - 1]:i += 1while sequence[i] > sequence[n - 1]:i += 1n -= 1if i < n:return Falsei = 0return True ?

24、 二叉樹中和為某一值的路徑

輸入一顆二叉樹的跟節點和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。路徑定義為從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。(注意: 在返回值的list中,數組長度大的數組靠前)

解答:

方法:遞歸方法

葉節點是葉子節點,度為0。深度優先遍歷。

遞歸先序遍歷樹,把結點加入路徑。若該結點是葉子結點則比較當前路徑和是否等于期待和。彈出結點,每一輪遞歸返回到父結點時,當前路徑也應該回退一個結點

注意:在判斷等于期待和后,每次需要新建一個list,否則至始至終result_list都指向同一個list。

target在遞歸中就是他所在那層的值,下一層遞歸所改變的值不會遞歸到上一層,pop后不需要加回去。

# -*- coding:utf-8 -*- # class TreeNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.left = None # ? ? ? ? self.right = None class Solution:# 返回二維列表,內部每個列表表示找到的路徑def __init__(self):self.result_list = []self.tmp_list = []def FindPath(self, root, expectNumber):# write code hereif not root:return self.tmp_listself.tmp_list.append(root.val)expectNumber -= root.valif expectNumber == 0 and not root.left and not root.right:new_list = []for i in self.tmp_list:new_list.append(i)self.result_list.append(new_list)self.FindPath(root.left,expectNumber)self.FindPath(root.right,expectNumber)self.tmp_list.pop()return self.result_list

25、復雜鏈表的復制

輸入一個復雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果為復制后復雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空

解答:

方法1:三步法:

*1、遍歷鏈表,復制每個結點,如復制結點A得到A1,將結點A1插到結點A后面;

*2、重新遍歷鏈表,復制老結點的隨機指針給新結點,如A1.random = A.random.next;

*3、拆分鏈表,將鏈表拆分為原鏈表和復制后的鏈表

方法2:遞歸法。

直接復制原鏈表,但是復制鏈表random指向的是原復雜鏈表

# -*- coding:utf-8 -*- # class RandomListNode: # ? ? def __init__(self, x): # ? ? ? ? self.label = x # ? ? ? ? self.next = None # ? ? ? ? self.random = None class Solution:# 返回 RandomListNodedef Clone(self, pHead):# write code hereif not pHead:returncurHead = pHeadwhile curHead:node = RandomListNode(curHead.label)node.next = curHead.nextcurHead.next = nodecurHead = node.nextcurHead = pHeadwhile curHead:node = curHead.nextif curHead.random:node.random = curHead.random.nextcurHead = node.nextcurHead = pHeadcopHead = pHead.nextwhile curHead.next:tmp = curHead.nextcurHead.next = tmp.nextcurHead = tmpreturn copHead# curhead = pHead# cophead = pHead.next# tmp = pHead.next# while curhead.next:# ? ? curhead.next = tmp.next# ? ? curhead = tmp# ? ? tmp = tmp.next# return copheaddef Clone(self, pHead):# write code hereif not pHead:returncurhead = pHeadcophead = RandomListNode(curhead.label)cophead.next = curhead.nextcophead.random = curhead.randomcophead.next = self.Clone(curhead.next)return cophead

26、二叉搜索樹與雙向鏈表

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。

解答:

方法1:遞歸

1、將左子樹構造成雙鏈表,并返回鏈表頭節點。

2、定位至左子樹雙鏈表最后一個節點。

3、如果左子樹鏈表不為空的話,將當前root追加到左子樹鏈表。

4、將右子樹構造成雙鏈表,并返回鏈表頭節點。

5、如果右子樹鏈表不為空的話,將該鏈表追加到root節點之后。

6、根據左子樹鏈表是否為空確定返回的節點。

方法2:非遞歸

1、核心是中序遍歷的非遞歸算法。

2、修改當前遍歷節點與前一遍歷節點的指針指向。

# -*- coding:utf-8 -*- # class TreeNode: # ? ? def __init__(self, x): # ? ? ? ? self.val = x # ? ? ? ? self.left = None # ? ? ? ? self.right = None class Solution:def Convert(self, pRootOfTree):# write code hereif not pRootOfTree:returnif not pRootOfTree.left and not pRootOfTree:return pRootOfTreeleft = self.Convert(pRootOfTree.left)node = leftwhile left and node.right:node = node.rightif left:node.right = pRootOfTreepRootOfTree.left = noderight = self.Convert(pRootOfTree.right)if right:pRootOfTree.right = rightright.left =pRootOfTreeif left:return leftelse:return pRootOfTreedef Convert(self, pRootOfTree):# write code hereif not pRootOfTree:returnif not pRootOfTree.left and not pRootOfTree:return pRootOfTreenode = pRootOfTreestack = []res_stack = []while node or stack:while node:stack.append(node)node = node.leftnode = stack.pop()res_stack.append(node)node = node.rightresult = res_stack[0]while res_stack:top = res_stack.pop(0)if res_stack:top.right = res_stack[0]res_stack[0].left = topreturn result

27、字符串的排列

輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。

解答:

方法1:基于回溯法思想

遞歸的思想,進行全排列,解析

方法2:字典序全排列算法,解析

# -*- coding:utf-8 -*- class Solution:def __init__(self):self.result = [] ?def Permutation(self, ss):ss = list(ss)begin = 0end = len(ss) - 1self.Permutation_Part(ss, begin, end)return sorted(self.result) ?def Permutation_Part(self, ss, begin, end):if begin == end:self.result.append(''.join(ss))returnfor i in range(begin, end + 1):if self.is_swap(ss, begin, i):ss[begin], ss[i] = ss[i], ss[begin]self.Permutation_Part(ss, begin + 1, end)ss[begin], ss[i] = ss[i], ss[begin] ?def is_swap(self, ss, begin, k):for i in range(begin, k):if ss[i] == ss[k]:return Falsereturn Trueclass Solutin():def Permutation(self, ss):# write code heress = list(ss)ss_len = len(ss)if ss_len == 0:return []result = []result.append(''.join(ss))while True:i = ss_len - 1while ss[i - 1] >= ss[i] and i >= 1:i -= 1if i == 0:breakm = iwhile m < ss_len and ss[m] > ss[i - 1] :m += 1ss[m - 1], ss[i - 1] = ss[i - 1], ss[m - 1]ss[i:] = sorted(ss[i:])result.append(''.join(ss))return result

28、數組中出現次數超過一半的數字

數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度為9的數組{1,2,3,2,2,2,5,4,2}。由于數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。

解答:

方法1:利用字典存儲,在遍歷中進行判斷value是否大于數組的一半,時間復雜度O(n),空間復雜度O(n)

方法2:

有一個士兵和他自己打架就贏一分,和別人打架就輸一分,他的分數是零就出局了。從下一個排號的開始(也可能是他自己)再進行以上,一直比到最后還有分的那個,就可能是勝利者(如果這個勝利者是恰巧贏了那幾局,就說明那個出現最多的那個士兵并不存在,所以最后重新計數)時間復雜度O(2*n),空間復雜度O(1)

# -*- coding:utf-8 -*- class Solution:def MoreThanHalfNum_Solution(self, numbers):# write code herenumber_len = len(numbers)number_dict = {}res = []for i in range(number_len):if numbers[i] not in number_dict:number_dict[numbers[i]] = 0number_dict[numbers[i]] += 1if number_dict[numbers[i]] > int(number_len / 2):return numbers[i]return 0 ?def MoreThanHalfNum_Solution(self, numbers):# write code hereif len(numbers) == 0:return 0numbers_len = len(numbers)tag = numbers[0]count = 1for i in range(1,numbers_len):if numbers[i] == tag:count +=1else:count -= 1if count == 0:tag = numbers[i]count = 1count = 0for i in numbers:if i == tag:count += 1if count > int(numbers_len / 2):return tagreturn 0

29、最小的K個數

輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。

解答:

方法:主要考慮的是海量數據下內存不夠的情況,使用堆排序,求最小的K個數,則建立K個數的大頂堆,時間復雜度為O(KlogK),將剩余的元素和堆頂元素比較,小于堆頂元素的進行替換,并刷新大頂堆。最終時間復雜度為O(NlogK)

# -*- coding:utf-8 -*- class Solution:def GetLeastNumbers_Solution(self, tinput, k):if len(tinput) < k or k == 0:return []min_input = tinput[:k]self.HeapSort(min_input)for i in tinput[k:]:if i < min_input[0]:min_input[0] = iself.HeapSort(min_input)return min_input[::-1] ?def HeapSort(self,min_input):k = len(min_input)i = int(k / 2) - 1while i >= 0:self.HeapAdjust(min_input, i, k)i -= 1j = k - 1while j > 0:min_input[0], min_input[j] = min_input[j], min_input[0]self.HeapAdjust(min_input, 0, j)j = j - 1return min_input ?def HeapAdjust(self,min_input,i,n):j = i * 2 + 1tag = min_input[i]while j < n:if j < n - 1 and min_input[j] > min_input[j+1]:j = j + 1if min_input[j] < tag:min_input[i] = min_input[j]i = jelse:breakj = j * 2 + 1min_input[i] = tag

30、連續子數組的最大和

HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會后,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,并期望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和為8(從第0個開始,到第3個為止)。給一個數組,返回它的最大連續子序列的和,你會不會被他忽悠住?(子向量的長度至少是1)

解答:

方法:動態規劃

# -*- coding:utf-8 -*-
class Solution:
? ?def FindGreatestSumOfSubArray(self, array):
? ? ? ?# write code here
? ? ? ?res = array[0]
? ? ? ?tmp = array[0]
? ? ? ?for i in range(1,len(array)):
? ? ? ? ? ?tmp = max(tmp + array[i],array[i])
? ? ? ? ? ?res = max(res,tmp)
? ? ? ?return res

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。