劍指Offer題解(Python版)
- 二叉樹的映象
- 連結串列中環的入口結點
- 刪除連結串列中重複的結點
- 從尾到頭列印連結串列
- 斐波那契數列
- 跳臺階
- 變態跳臺階
- 矩形覆蓋
- 把字串轉換成整數
- 平衡二叉樹
- 和為S的連續正數序列
- 左旋轉字串
- 數字在排序陣列中出現的次數
- 陣列中只出現一次的數字
- 翻轉單詞順序列
- 二叉樹的深度
- 和為S的兩個數字
- 順時針列印矩陣
- 二叉樹的下一個結點
- 對稱的二叉樹
- 把二叉樹列印成多行
- 按之字形順序列印二叉樹
- 序列化二叉樹
- 二叉搜尋樹的第k個結點
- 資料流中的中位數
- 重建二叉樹
- 滑動視窗的最大值
- 用兩個棧實現佇列
- 旋轉陣列的最小數字
- 醜數
- 兩個連結串列的第一個公共結點
- 第一個只出現一次的字元位置
- 陣列中的逆序對
- 連續子陣列的最大和
- 最小的K個數
- 陣列中出現次數超過一半的數字
- 整數中1出現的次數(從1到n整數中1出現的次數)
- 把陣列排成最小的數
- 陣列中重複的數字
- 構建乘積陣列
- 二維陣列中的查詢
- 撲克牌順子
- 孩子們的遊戲(圓圈中最後剩下的數)
- 正則表示式匹配
- 表示數值的字串
- 字元流中第一個不重複的字元
- 替換空格
- 矩陣中的路徑
- 機器人的運動範圍
- 求1+2+3+…+n
- 不用加減乘除做加法
- 二叉搜尋樹與雙向連結串列
- 複雜連結串列的複製
- 字串的排列
- 二進位制中1的個數
- 連結串列中倒數第k個結點
- 合併兩個排序的連結串列
- 反轉連結串列
- 樹的子結構
- 數值的整數次方
- 調整陣列順序使奇數位於偶數前面
- 包含min函式的棧
- 二叉樹中和為某一值的路徑
- 從上往下列印二叉樹
- 二叉搜尋樹的後序遍歷序列
- 棧的壓入、彈出序列
(1) 二叉樹的映象(Symmetric Tree)
牛客網連結
Leetcode連結
class Solution:
# 返回映象樹的根節點
def Mirror(self, root):
if root == None:
return
self.Mirror(root.left)
self.Mirror(root.right)
root.left,root.right = root.right,root.left
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head == None or head.next == None:
return False
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
而尋找環的入口,假設入口結點距離頭結點a個單位,fast和slow相遇在距離入口結點b個單位的位置,環剩下的長度為c,則有a+b+c+b = 2*(a+b) -> a = c
因此,在重合時候,將fast置為head,再一步一步地走,當與slow重合時的結點即為入口結點
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
if pHead== None or pHead.next == None:
return None
fast = slow = pHead
while(fast and fast.next):
slow = slow.next
fast = fast.next.next
if slow == fast:
fast = pHead
while(fast!=slow):
fast = fast.next
slow = slow.next
return fast
return None
class Solution:
def deleteDuplication(self, pHead):
# write code here
pos = pHead
ret = ListNode(-1)
tmp = ret
flag = False
while(pos and pos.next):
if pos.val == pos.next.val:
flag = True
pos.next = pos.next.next
else:
if flag:
flag = False
else:
tmp.next = ListNode(pos.val)
tmp = tmp.next
pos = pos.next
if pos and flag==False:
tmp.next = ListNode(pos.val)
return ret.next
class Solution:
# 返回從尾部到頭部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
ret = []
head = listNode
while(head):
ret.append(head.val)
head = head.next
ret.reverse()
return ret
(5)求斐波那契數列的第n項
斐波那契數列
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
if n == 0:
return 0
if n==1 or n==2:
return 1
memories = [1,1]
for i in range(n-2):
memories.append(memories[-1]+memories[-2])
return memories[-1]
(6)跳臺階
一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
# -*- coding:utf-8 -*-
class Solution:
def jumpFloor(self, number):
# write code here
'''
n = 1 : 1
n = 2 : 1+1 = 2
n = 3 : dp[n-2]+dp[n-1]
'''
if number == 1 or number == 2:
return number
dp = [1,2]
for i in range(number-2):
dp.append(dp[-1]+dp[-2])
return dp[-1]
(7)變態跳臺階
一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
思考:在dp[n] = dp[n-1] + dp[n-2] + .. + dp[1] + 1(直接跳n)步驟
即
class Solution:
def jumpFloorII(self, number):
# write code here
if number == 1 or number == 2:
return number
ret = sum_ = 3
for i in range(number-2):
ret = sum_+1
sum_+=ret
return ret
(8)矩形覆蓋
我們可以用2*1的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?
思考: 2*1 1 種; 2*2 2種 2*3 3種 2*4 5種
# -*- coding:utf-8 -*-
class Solution:
def rectCover(self, number):
# write code here
if number<=2:
return number
dp = [1,2]
for i in range(number-2):
dp.append(dp[-1]+dp[-2])
return dp[-1]
(9)把字串轉換成整數
把字串轉換成整數
將一個字串轉換成一個整數,要求不能使用字串轉換整數的庫函式。 數值為0或者字串不是一個合法的數值則返回0
思考:如果有正負號,需要在數字之前,出現其他字元或者字串為空都非法返回0
class Solution:
def StrToInt(self, s):
# write code here
flag = True
pos = 1
ret = None
if s=='':
return 0
for i in s:
if i=='+' or i=='-':
if flag:
pos = -1 if i=='-' else 1
flag = False
else:
return 0
elif i>='0' and i<='9':
flag = False
if ret == None:
ret = int(i)
else:
ret = ret*10+int(i)
else:
return 0
return pos*ret if ret else 0
(10)平衡二叉樹的判斷
思考:BST的定義為,原問題拆分為計算樹高度和判斷高度差
class Solution:
def Treeheight(self,pRoot):
if pRoot == None:
return 0
if pRoot.left == None and pRoot.right == None:
return 1
lh = self.Treeheight(pRoot.left)
rh = self.Treeheight(pRoot.right)
return max(rh,lh)+1
def IsBalanced_Solution(self, pRoot):
# write code here
if pRoot == None:
return True
return abs(self.Treeheight(pRoot.left)-self.Treeheight(pRoot.right))<=1
(11)和為S的連續正數序列
輸出所有和為S的連續正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序
思考:S%奇數==0 或者S%偶數==偶數/2 就說明有這個連續序列,但是注意是正數序列,可能會出現越界情況
class Solution:
def FindContinuousSequence(self, tsum):
# write code here
k = 2
ret = []
for k in range(2,tsum):
if k%2==1 and tsum%k==0:
tmp = []
mid = tsum/k
if mid-k/2>0:
for i in range(mid-k/2,mid+k/2+1):
tmp.append(i)
ret.append(tmp[:])
elif k%2==0 and (tsum%k)*2==k:
mid = tsum/k
tmp = []
if mid-k/2+1>0:
for i in range(mid-k/2+1,mid+k/2+1):
tmp.append(i)
ret.append(tmp[:])
ret.sort()
return ret
(12)左旋轉字串
對於一個給定的字元序列S,請你把其迴圈左移K位後的序列輸出。
思考:需要先K= K%len(S)
# -*- coding:utf-8 -*-
class Solution:
def LeftRotateString(self, s, n):
# write code here
if s == '':
return s
n = n%len(s)
return s[n:]+s[0:n]
(13)數字在排序陣列中出現的次數
數字在排序陣列中出現的次數
思考:原來是可以用hash做的,但是因為是排序陣列,所以可以用二分查詢
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
# write code here
start = 0
end = len(data)-1
while(start<=end):
mid = (start+end)/2
if data[mid]==k:
cnt = 0
tmp = mid
while(tmp>=0 and data[tmp]==k):
cnt+=1
tmp-=1
tmp = mid+1
while(tmp<len(data) and data[tmp]==k):
cnt+=1
tmp+=1
return cnt
elif data[mid]>k:
end = mid-1
else:
start = mid+1
return 0
(14)陣列中只出現一次的數字
一個整型數組裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字
思考:用hash;或者位運算
首先利用0 ^ a = a; a^a = 0的性質
兩個不相等的元素在位級表示上必定會有一位存在不同,
將陣列的所有元素異或得到的結果為不存在重複的兩個元素異或的結果,
據異或的結果1所在的最低位,把數字分成兩半,每一半里都還有一個出現一次的資料和其他成對出現的資料,
問題就轉化為了兩個獨立的子問題“陣列中只有一個數出現一次,其他數都出現了2次,找出這個數字”。
class Solution:
# 返回[a,b] 其中ab是出現一次的兩個數字
def FindNumsAppearOnce(self, array):
# write code here
ans,a1,a2,flag= 0,0,0,1
for num in array:
ans = ans ^ num
while(ans):
if ans%2 == 0:
ans = ans >>1
flag = flag <<1
else:
break
for num in array:
if num & flag:
a1 = a1 ^ num
else:
a2 = a2 ^ num
return a1,a2
# -*- coding:utf-8 -*-
class Solution:
def ReverseSentence(self, s):
# write code here
ret = s.split(" ")
ret.reverse()
return ' '.join(ret)
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def TreeDepth(self, pRoot):
# write code here
if pRoot == None:
return 0
if pRoot.left == None and pRoot.right==None:
return 1
return max(self.TreeDepth(pRoot.left),self.TreeDepth(pRoot.right))+1
(17)和為S的兩個數字
輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,是的他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。
hash
# -*- coding:utf-8 -*-
class Solution:
def FindNumbersWithSum(self, array, tsum):
# write code here
memorys= {}
ret = []
for num in array:
if tsum-num in memorys:
if ret == []:
ret = [tsum-num,num]
elif ret and ret[0]*ret[1]>(tsum-num)*num:
ret = [tsum-num,num]
else:
memorys[num] = 1
return ret
# -*- coding:utf-8 -*-
class Solution:
# matrix型別為二維列表,需要返回列表
def printMatrix(self, matrix):
# write code here
m=len(matrix)
ans=[]
if m==0:
return ans
n=len(matrix[0])
#ans = [[0 for i in range(n)] for j in range(n)]
#print ans
upper_i =0;lower_i=m-1;left_j=0;right_j=n-1
num=1
i=0;j=0
right_pointer=1
down_pointer=0
while(num<=m*n):
ans.append(matrix[i][j])
if right_pointer==1:
if j<right_j:
j=j+1
else:
right_pointer=0
down_pointer=1
upper_i = upper_i+1
i = i+1
elif down_pointer == 1:
if i<lower_i:
i = i+1
else:
right_pointer=-1
down_pointer=0
right_j = right_j -1
j = j-1
elif right_pointer ==-1:
if j > left_j:
j=j-1
else:
right_pointer=0
down_pointer=-1
lower_i =lower_i-1
i = i-1
elif down_pointer == -1:
if i > upper_i:
i=i-1
else:
right_pointer=1
down_pointer=0
left_j = left_j +1
j = j+1
num=num+1
return ans
(19)* 二叉樹的下一個結點
二叉樹的下一個結點
給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指標。
思路:中序遍歷的順序為LVR
則有以下三種情況:
a. 如果該結點存在右子結點,那麼該結點的下一個結點是右子結點樹上最左子結點
b. 如果該結點不存在右子結點,且它是它父結點的左子結點,那麼該結點的下一個結點是它的父結點
c. 如果該結點既不存在右子結點,且也不是它父結點的左子結點,則需要一路向祖先結點搜尋,直到找到一個結點,該結點是其父親結點的左子結點。如果這樣的結點存在,那麼該結點的父親結點就是我們要找的下一個結點。
class Solution:
def GetNext(self, pNode):
# write code here
# left root right
if pNode == None:
return None
if pNode.right:
tmp = pNode.right
while(tmp.left):
tmp = tmp.left
return tmp
p = pNode.next
while(p and p.right==pNode):
pNode = p
p = p.next
return p
class Solution:
def Symmetrical(self,Lnode,Rnode):
if Lnode == None and Rnode == None:
return True
if Lnode and Rnode:
return Lnode.val == Rnode.val and self.Symmetrical(Lnode.right,Rnode.left) and self.Symmetrical(Lnode.left,Rnode.right)
else:
return False
def isSymmetrical(self, pRoot):
# write code here
if pRoot == None:
return True
return self.Symmetrical(pRoot.left,pRoot.right)
(21)把二叉樹列印成多行
從上到下按層列印二叉樹,同一層結點從左至右輸出。每一層輸出一行。
class Solution:
# 返回二維列表[[1,2],[4,5]]
def Print(self, pRoot):
# write code here
if pRoot == None:
return []
stack = [pRoot]
ret = []
while(stack):
tmpstack = []
tmp = []
for node in stack:
tmp.append(node.val)
if node.left:
tmpstack.append(node.left)
if node.right:
tmpstack.append(node.right)
ret.append(tmp[:])
stack = tmpstack[:]
return ret
class Solution:
def Print(self, pRoot):
# write code here
if pRoot == None:
return []
stack = [pRoot]
step = 1
ret = []
while(stack):
tmpstack = []
tmp = []
for node in stack:
tmp+=[node.val]
if node.left:
tmpstack.append(node.left)
if node.right:
tmpstack.append(node.right)
if step%2==0:
tmp.reverse()
ret.append(tmp)
step += 1
stack = tmpstack[:]
return ret
class Solution:
def Serialize(self, root):
# write code here
def doit(node):
if node:
vals.append(str(node.val))
doit(node.left)
doit(node.right)
else:
vals.append('#')
vals = []
doit(root)
return ' '.join(vals)
def Deserialize(self, s):
# write code here
def doit():
val = next(vals)
if val == '#':
return None
node = TreeNode(int(val))
node.left = doit()
node.right = doit()
return node
vals = iter(s.split())
return doit()
from heapq import *
class MedianFinder:
def __init__(self):
self.heaps = [], []
def addNum(self, num):
small, large = self.heaps
heappush(small, -heappushpop(large, num))
if len(large) < len(small):
heappush(large, -heappop(small))
def findMedian(self):
small, large = self.heaps
if len(large) > len(small):
return float(large[0])
return (large[0] - small[0]) / 2.0
(25)* 二叉平衡樹中的第k小數
二叉搜尋樹中的第k大結點
Leetcode 230. Kth Smallest Element in a BST
思路:BST的中序遍歷就是一個有序陣列,需要注意到Leetcode中限制了k在[1,樹結點個數]而牛客網沒有,所以需要考慮k的值有沒有超出
class Solution:
# 返回對應節點TreeNode
def KthNode(self, pRoot, k):
# write code here
stack = []
node = pRoot
while node:
stack.append(node)
node = node.left
cnt = 1
while(stack and cnt<=k):
node = stack.pop()
right = node.right
while right:
stack.append(right)
right = right.left
cnt+=1
相關推薦
劍指Offer題解(Python版)
二叉樹的映象
連結串列中環的入口結點
刪除連結串列中重複的結點
從尾到頭列印連結串列
斐波那契數列
跳臺階
變態跳臺階
矩形覆蓋
把字串轉換成整數
平衡二叉樹
和為S的連續正數序列
左旋轉字串
數字在排序陣列中出現的次數
陣列中只出現一次的數字
翻轉單詞順序列
劍指Offer題解【Python版】
題目連結
9. Fizz Buzz 問題
給你一個整數n. 從 1 到 n 按照下面的規則列印每個數:
如果這個數被3整除,列印fizz.
如果這個數被5整除,列印buzz.
如果這個數能
劍指offer題解(十一):c++&java
序列化二叉樹
題目描述
請實現兩個函式,分別用來序列化和反序列化二叉樹
對於序列化:使用前序遍歷,遞迴的將二叉樹的值轉化為字元,並且在每次二叉樹的結點不為空時,在轉化val所得的字元之後新增一個’ , ‘作為分割。對於空節點則以 ‘#’ 代替。
對
劍指offer題解(連續子陣列的最大和)
題目描述
HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-
劍指offer題解(陣列中出現次數超過一半的數字)
題目描述
陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。
解題思路
先找到出現次數最多
劍指offer題解(二叉樹與雙向連結串列)
題目描述
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。
解題思路
中序遍歷搜尋二叉樹,用pre儲存中序遍歷的前一個節點,cur為當前節點,然後使pre->right=cu
劍指offer題解(複雜連結串列的複製)
題目描述
輸入一個複雜連結串列(每個節點中有節點值,以及兩個指標,一個指向下一個節點,另一個特殊指標指向任意一個節點),返回結果為複製後複雜連結串列的head。(注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空)
思路
新建一個連結串列,先不管random指標,根據n
劍指Offer題解(二)陣列問題
#include<vector>
using namespace std;
#pragma region 二維陣列中的查詢 二維陣列
//在一個二維陣列中(每個一維陣列的長度相同),每一行都按照從左到右遞增的順序排序,
//每一列都按照從上到下
劍指Offer題解(三)字串問題
#include<vector>
using namespace std;
// getline(cin, str); //一行一行輸入可輸入空格
#pragma region 替換空格 字串
//請實現一個函式,將一個字串中的每個空格替換成“
劍指offer題解(十):C++&java
二叉搜尋樹的後序遍歷序列
題目描述
輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。假設輸入的陣列的任意兩個數字都互不相同。
例如,下圖是後序遍歷序列 3,1,2 所對應的二叉搜尋樹。
解題思路
BST的後序序列的合法序列是
劍指offer題解(四):java&c++
矩陣中的路徑
題目描述
請設計一個函式,用來判斷在一個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向左,向右,向上,向下移動一個格子。如果一條路徑經過了矩陣中的某一個格子,則該路徑不能再進入該格子。
劍指offer題解(八):c++&java
二叉樹的映象
題目描述
操作給定的二叉樹,將其變換為源二叉樹的映象。
解題思路
c++
class Solution {
private:
void swapfun(TreeNode *root)
{
T
劍指offer題解(十三)
開篇
十幾天沒有刷題了,今天又可以開始刷題啦
連續子陣列的最大和
題目描述
HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好
劍指offer系列(十二)最小的k個數, 連續子陣列的最大和,整數中1出現的個數
最小的k個數
題目描述
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
解題思路:
思路1,這一題應用堆排序演算法複雜度只有O(nlog k),堆是完全二叉樹的一種,最大堆就是最上面的數是最大的,該方法基於二
劍指offer系列(十一)二叉搜尋樹與雙向連結串列, 字串的排序
二叉搜尋樹與雙向連結串列
題目描述
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。
解題思路:
由於輸入的一個二叉搜尋樹,其左子樹小於右子樹的值,這位後面的排序做了準備,因為只需要中序遍歷即可,將所有 的節點儲存
劍指offer系列(十六)翻轉單詞順序列,撲克牌順子,孩子們的遊戲(圓圈中最後剩下的數)
翻轉單詞順序列
題目描述
牛客最近來了一個新員工Fish,每天早晨總是會拿著一本英文雜誌,寫些句子在本子上。同事Cat對Fish寫的內容頗感興趣,有一天他向Fish借來翻看,但卻讀不懂它的意思。例如,“student. a am I”。後來才意識到,這傢伙原來把句子單詞的順序翻轉了,正確的句
劍指offer系列(十五)和為S的連續正數序列,和為s的兩個數字,左旋轉字串
和為S的連續正數序列
題目描述
小明很喜歡數學,有一天他在做數學作業時,要求計算出9~16的和,他馬上就寫出了正確答案是100。但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和為100(至少包括兩個數)。沒多久,他就得到另一組連續正數和為100的序列:18,19,20,21,22。現
劍指offer系列(十四)二叉樹的深度,平衡二叉樹,陣列中只出現一次的數字
二叉樹的深度
題目描述
輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度為樹的深度。
解題思路:
利用遞迴實現。如果一棵樹只有一個結點,那麼它的深度為1。遞迴的時候無需判斷左右子樹是否存在,因為如果該節點 為葉節點,它的左右
劍指offer系列(十七)求1+2+3+...+n,不用加減乘除做加法,把字串轉換成整數
求1+2+3+...+n
題目描述
求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。
解題思路:
法一:利用python的特性
法二:用兩個函式,一個遞迴,另一個終止遞迴。如果對n連續進
劍指Offer-- 翻轉鏈表 (python版)
head 鏈表 pytho blog write ini pre 當前 返回 輸入一個鏈表,反轉鏈表後,輸出鏈表的所有元素。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
#