目錄
二維數組中的查找
題目描述
在一個二維數組中(每個一維數組的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
# -*- coding:utf-8 -*-
class Solution:
# array 二維列表
def Find(self, target, array):
# write code here
flag = 0
for i in array:
for j in i:
if target ==j:
flag = 1
if flag ==1:
return True
else:
return False
替換空格
題目描述
請實現一個函數,將一個字符串中的每個空格替換成“%20”。例如,當字符串爲We Are Happy.則經過替換之後的字符串爲We%20Are%20Happy。
# -*- coding:utf-8 -*-
class Solution:
# s 源字符串
def replaceSpace(self, s):
# write code here
list_s = list(s)
for index,i in enumerate(list_s):
if i == " ":
list_s[index] = "%20"
s = "".join(list_s)
return s
從尾到頭打印鏈表
題目描述
輸入一個鏈表,按鏈表從尾到頭的順序返回一個ArrayList。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回從尾部到頭部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
arraylist = []
head = listNode
p = head
if listNode == None:
return []
while p != None:
arraylist.append(p.val)
p = p.next
arraylist.reverse()
return arraylist
重建二叉樹
題目描述
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回構造的TreeNode根節點
def reConstructBinaryTree(self, pre, tin):
# write code here
# TODO:檢查是否爲空,若只有1個值的時候直接返回
if len(pre)==0:
return None
if len(pre)==1:
return TreeNode(pre[0])
for index,i in enumerate(tin):
if i == pre[0]:
root_index = index
break
root = TreeNode(pre[0])
root_left_tin = tin[:root_index]
root_right_tin = tin[root_index+1:]
#這裏可以改寫成index用法,index輸出序號位置,可以替代length
root_left_pre = pre[1:len(root_left_tin)+1]
root_right_pre = pre[len(root_left_tin)+1:]
root.left = self.reConstructBinaryTree(root_left_pre,root_left_tin)
root.right = self.reConstructBinaryTree(root_right_pre,root_right_tin)
return root
用兩個棧實現隊列
題目描述
用兩個棧來實現一個隊列,完成隊列的Push和Pop操作。 隊列中的元素爲int類型。
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stack1 = []
self.stack2 = []
def push(self, node):
# write code here
self.stack1.append(node)
return self.stack1
def pop(self):
# return xx
self.stack2.append(self.stack1[0])
del self.stack1[0]
return self.stack2[-1]
旋轉數組的最小數字
題目描述
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。
輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素。
例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。
NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if len(rotateArray)==0:
return 0
min = rotateArray[0]
for i in rotateArray:
if i<min:
min = i
return min
斐波那契數列
題目描述
大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項(從0開始,第0項爲0,第1項是1)。
n<=39
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
# write code here
first = 0
second = 1
while(n>0): #累加避免遞歸
second = first + second
first = second - first
n = n-1
return first #這裏之所以要返回first,是因爲n差兩個位置
跳臺階
題目描述
一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法(先後次序不同算不同的結果)。
# -*- coding:utf-8 -*-
class Solution:
def jumpFloor(self, number):
# write code here
first=1
second =2
while number>1:
second = first+second
first = second - first
number = number-1
return first
變態跳臺階
題目描述
一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
# -*- coding:utf-8 -*-
class Solution:
def jumpFloorII(self, number):
# write code here
#1 2 4 8
return pow(2,number-1)
矩陣覆蓋
題目描述
我們可以用2*1的小矩形橫着或者豎着去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?
比如n=3時,2*3的矩形塊有3種覆蓋方法:
# -*- coding:utf-8 -*-
class Solution:
def rectCover(self, number):
# write code here
while number == 0:
return number
first = 1
second = 2
while number>=2:
second = first + second
first = second -first
number = number-1
return first
#這裏的number也是width,height固定
二進制中1的個數
題目描述
輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1(self, n):
# write code here
number = 0
for i in range(32):
#整數具有32位,右移n位相當於除以2的n次方,&爲位運算,即比較2,3,4...32位是否爲1
if (n>>i) & 1 != 0:
number = number+1
return number
數值的整數次方
題目描述
給定一個double類型的浮點數base和int類型的整數exponent。求base的exponent次方。
保證base和exponent不同時爲0
# -*- coding:utf-8 -*-
class Solution:
def Power(self, base, exponent):
# write code here
return pow(base,exponent)
調整數組順序使奇數位於偶數前面
題目描述
輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,所有的偶數位於數組的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變
# -*- coding:utf-8 -*-
class Solution:
def reOrderArray(self, array):
# write code here
jishu = []
oushu = []
if len(array)==0:
return []
for i in array:
if i%2==0:
oushu.append(i)
else :
jishu.append(i)
return jishu + oushu
鏈表中倒數第k個節點
題目描述
輸入一個鏈表,輸出該鏈表中倒數第k個結點
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
# write code here
if (head== None) or (k<=0):
return None
p1 = head
p2 = head
count = 0
#因爲0本身就要運行一次,所以這裏設置爲k-1
while count<k-1:
if p2.next != None:
p2 = p2.next
count = count+1
else:
return None
while p2.next != None:
p1 = p1.next
p2 = p2.next
return p1
反轉鏈表
題目描述
輸入一個鏈表,反轉鏈表後,輸出新鏈表的表頭。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
#本來需要考慮pHead.next的情況,但是檢查程序時發現下面包含了
if pHead == None:
return None
pre = None
cur = pHead
while cur != None:
temp = cur.next #先存起來準備遍歷,不然不好向下走
cur.next = pre #翻轉鏈表
pre = cur #總是標誌前一個
cur = temp #這裏準備向下走
return pre #最後的pre就是cur的所在地,curl在上一輪爲None了
合併兩個排序的鏈表
題目描述
輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回合併後列表
def Merge(self, pHead1, pHead2):
# write code here
mergeHead = ListNode(100) #設置一個足夠大的數,前面head設爲空節點,返回next即可
cur = mergeHead
while pHead1 and pHead2:
#確定指針移到哪個鏈表上
if pHead1.val <pHead2.val:
mergeHead.next = pHead1
pHead1 = pHead1.next
else:
mergeHead.next = pHead2
pHead2 = pHead2.next
mergeHead = mergeHead.next #指針要移動
if pHead1 == None:
mergeHead.next = pHead2
else:
mergeHead.next = pHead1
# return mergeHead 如果這裏這麼返回mergeHead指向鏈表的部分,不行
return cur.next
樹的子結構
題目描述
輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def HasSubtree(self, pRoot1, pRoot2):
# write code here
if pRoot1 == None or pRoot2 ==None:
return False
# 左右子樹是否存在其子結構,這裏已經不是空樹了
return self.IsSubtree(pRoot1,pRoot2) or self.HasSubtree(pRoot1.left,pRoot2) or self.HasSubtree(pRoot1.right,pRoot2)
def IsSubtree(self,A,B):
if B==None:
return True
if A == None or A.val!=B.val:
return False
return self.IsSubtree(A.left,B.left) and self.IsSubtree(A.right,B.right)
二叉樹的鏡像
題目描述
操作給定的二叉樹,將其變換爲源二叉樹的鏡像。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回鏡像樹的根節點
def Mirror(self, root):
# write code here
if not root:
return None
root.left,root.right = root.right,root.left #python支持對象的交換
self.Mirror(root.left) #因爲已經交換過了,直接在下一層進行交換
self.Mirror(root.right)
return root
順時針打印矩陣
題目描述
輸入一個矩陣,按照從外向裏以順時針的順序依次打印出每一個數字,例如,如果輸入如下4 X 4矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 則依次打印出數字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
# -*- coding:utf-8 -*-
class Solution:
# matrix類型爲二維列表,需要返回列表
def printMatrix(self, matrix):
# write code here
res = []
if matrix == None:
return res
low,high,left,right = 0,len(matrix)-1,0,len(matrix[0])-1 #進行方向標記
while low<=high and left<=right:
# 先向右
for i in range(left,right+1):
res.append(matrix[low][i])
# 再向下
for i in range(low+1,high+1):
res.append(matrix[i][right])
# 再向左(考慮只有1行的情況,避免重複訪問)
if low<high:
for i in range(right-1,left-1,-1):
res.append(matrix[high][i])
#再向上(考慮只有1列)
if left<right:
for i in range(high-1,low,-1):
res.append(matrix[i][left])
left = left+1
right = right-1
low = low+1
high = high-1
return res
包含min函數的棧
題目描述
定義棧的數據結構,請在該類型中實現一個能夠得到棧中所含最小元素的min函數(時間複雜度應爲O(1))。
注意:保證測試中不會當棧爲空的時候,對棧調用pop()或者min()或者top()方法。
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stack = []
self.min_stack = []
def push(self, node):
# write code here
self.stack.append(node)
if self.min_stack ==[] or node<=self.min_stack[-1]:
self.min_stack.append(node)
def pop(self):
# write code here
if self.stack == []:
return None
#這裏一定不能忘記判斷
if self.stack[-1]==self.min_stack[-1]:
self.min_stack.pop()
self.stack.pop()
def top(self):
# write code here
if self.stack ==[]:
return None
return self.stack[-1]
def min(self):
# write code here
return self.min_stack[-1]
棧的壓入彈出序列
題目描述
輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否可能爲該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)
# -*- coding:utf-8 -*-
class Solution:
def IsPopOrder(self, pushV, popV):
# write code here
if not pushV or len(popV) != len(pushV):
return False
new_stack = [] #用於模擬塞入數據
#j=0
for i in pushV:
new_stack.append(i)
#while new_stack[-1] == popV[0] and len(new_stack):
while len(new_stack) and new_stack[-1] == popV[0]:
new_stack.pop()
popV.pop(0) #pop順序也要移動,傳入0代表從左邊出棧
if len(new_stack):
return False
return True
從上往下打印二叉樹
題目描述
從上往下打印出二叉樹的每個節點,同層節點從左至右打印。
# -*- 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 here
#廣度遍歷
if not root:
return []
val = [] #存入值
node = [root] #存入節點
while len(node):
t = node.pop(0) #隊列的思想
val.append(t.val)
if t.left:
node.append(t.left)
if t.right:
node.append(t.right)
return val
二叉搜索樹的後序遍歷序列
題目描述
輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。
# -*- coding:utf-8 -*-
class Solution:
def VerifySquenceOfBST(self, sequence):
# write code here
if not sequence:
return False
return self.IsBST(sequence,0,len(sequence)-1) #判斷是否是二叉搜索樹
def IsBST(self,array,start,end):
if start >= end:
return True # 可以直接比較,就一個節點
#下面應該尋找i分界線,分爲左右子樹,準備遞歸
i = end -1
#遍歷時候先遍歷右子樹,所以都比根節點小,從後往前找分界點
while i>start and array[i]>array[end]:
i = i-1
#下面遍歷前半部分,即左子樹
j = 0
for j in range(i-1,start-1,-1):
if array[j]>array[end]:
return False
return self.IsBST(array,start,i-1) and self.IsBST(array,i,end-1)
二叉樹中和爲某一值的路徑
題目描述
輸入一顆二叉樹的根節點和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回二維列表,內部每個列表表示找到的路徑
def FindPath(self, root, expectNumber):
# write code here
#本質是個深度遍歷
if not root:
return []
if not root.left and not root.right and root.val == expectNumber:
return [[root.val]]
res = [] #這裏面存的對象應該是列表
left = self.FindPath(root.left,expectNumber-root.val)
right = self.FindPath(root.right,expectNumber-root.val)
for i in left+right:
res.append([root.val]+i)
return res
複雜鏈表的複製
題目描述
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針random指向一個隨機節點),請對此鏈表進行深拷貝,並返回拷貝後的頭結點。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
# -*- coding:utf-8 -*-
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
if not pHead:
return None
cur = pHead
# 進行節點的複製
while cur!=None:#這裏不能使用not
clone = RandomListNode(cur.label)
nextnode = cur.next
cur.next = clone
clone.next = nextnode
cur = nextnode #進行遍歷插入
# 第二趟遍歷,進行random的複製,random存在原random的下一個節點
cur = pHead
while cur!= None:
cur.next.random = cur.random.next if cur.random else None
cur = cur.next.next
# 進行拆分鏈表,通過斷開鏈接的方式
cur = pHead
cloneList = pHead.next
while cur!=None:
clone = cur.next
cur.next = clone.next
clone.next = clone.next.next if clone.next else None
cur = cur.next
return cloneList
二叉搜索樹與雙向鏈表
題目描述
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。
要求不能創建任何新的結點,只能調整樹中結點指針的指向。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def Convert(self, root):
# write code here
# 下面是遞歸版本
'''if not pRootOfTree:
return None
if not pRootOfTree.left and not pRootOfTree.right:
return pRootOfTree
# 先遍歷左子樹
left = self.Convert(pRootOfTree.left)
p = left
while left and p.right:
# 找到左子樹遍歷的最右節點,也就是對應鏈表的最右邊
p = p.right
# 加入根節點
if left:
p.right = pRootOfTree
pRootOfTree.left = p
right = self.Convert(pRootOfTree)
# 加入右子樹
if right:
right.left = pRootOfTree
pRootOfTree.right = right
return left if left else root'''
# 非遞歸要掌握
if not root:
return None
stack= []
resStack =[]
p = root
# 這個中序遍歷的非遞歸寫的太好;
while p or stack:
if p:
stack.append(p)
p = p.left
else:
node = stack.pop()
resStack.append(node)
p = node.right
resP = resStack[0]
while resStack:
top = resStack.pop(0) #從前向後pop()
if resStack:
top.right = resStack[0]
resStack[0].left = top
return resP
字符串的排列
題目描述
輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。
輸入描述:
輸入一個字符串,長度不超過9(可能有字符重複),字符只包括大小寫字母。
# -*- coding:utf-8 -*-
class Solution:
def Permutation(self, ss):
# write code here
if len(ss) <=1:
return ss
res = set() # 去重
for i in range(len(ss)):
for j in self.Permutation(ss[:i]+ss[i+1:]):
res.add(ss[i]+j)
return sorted(list(res))
數組中出現次數超過一半的數字
題目描述
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
partlength = int(len(numbers)/2)
# 使用一個字典存儲個數
#dictnum = collections.defaultdict()
dictnum = {}
for i in numbers:
#dictnum[numbers[i]].value +1 if value else 0
if i not in dictnum.keys():
dictnum[i] = 1
else :
dictnum[i] = dictnum[i] + 1
# 遍歷檢查
#for key , value in dictnum:
#if value > partlength:
#return key
#return 0
for key,value in dictnum.items():
if value >= partlength+1:
return key
return 0
最小的k個數
題目描述
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
# -*- coding:utf-8 -*-
class Solution:
def GetLeastNumbers_Solution(self, tinput, k):
# write code here
if k > len(tinput):
return []
sortedTinput = sorted(tinput)
return sortedTinput[:k]
連續子數組的最大和
題目描述
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
arraysum = []
if not array:
return None
if len(array)==1:
return array[0]
maxsum = float('-inf')
for i in range(len(array)):
# 都記錄下來即可
if maxsum<array[i]:
maxsum = array[i]
temp = array[i]
#maxsum都是與和作比較,但是沒有和數作比較,所以前面得加上判斷
for j in array[i+1:]:
temp = temp + j
if temp > maxsum:
maxsum = temp
return maxsum
整數中1出現的次數
題目描述
求出1~13的整數中1出現的次數,並算出100~1300的整數中1出現的次數?爲此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數(從1 到 n 中1出現的次數)。
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1Between1AndN_Solution(self, n):
# write code here
# 每次都是考慮一個數位上的1出現次數
count = 0 #1的個數
i = 1 # 切分位置
cur,after,before = 0,0,0
#這裏想百位就好理解,即i =100
while n/i !=0:
cur = (n/i) %10 #當前位
before = n/(i*10) # 高位
after = n-(n/i)*i # 低位
if cur ==0:
count +=before*i #百位上的1僅由高位決定
elif cur ==1:
count +=before*i + after+1 # 百位上的1由高位低位共同決定
else:
count+= (before+1)*i #僅由高位決定
i = i*10
return count
把數組排成最小的數
題目描述
輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字爲321323。
# -*- coding:utf-8 -*-
class Solution:
def PrintMinNumber(self, numbers):
# write code here
# 不要想多,就是兩兩比較,最後串起來
length = len(numbers)
if length ==0:
return ''
# 最後一個不用比較
for i in range(length-1):
for j in range(length-i-1):
if int(str(numbers[j])+str(numbers[j+1]))>int(str(numbers[j+1])+str(numbers[j])):
numbers[j+1],numbers[j] = numbers[j],numbers[j+1]
return int(''.join(str(i) for i in numbers))
醜數
題目描述
把只包含質因子2、3和5的數稱作醜數(Ugly Number)。例如6、8都是醜數,但14不是,因爲它包含質因子7。 習慣上我們把1當做是第一個醜數。求按從小到大的順序的第N個醜數。
# -*- coding:utf-8 -*-
class Solution:
def GetUglyNumber_Solution(self, index):
# write code here
if index<=0:
return False
if index ==1:
return 1
ugly = [1]
indextwo = 0
indexthree = 0
indexfive = 0
for i in range(1,index):
# 沒必要維護三個隊列,記錄位置即可
ugly.append(min(ugly[indextwo]*2,ugly[indexthree]*3,ugly[indexfive]*5))
if ugly[i] == ugly[indextwo]*2:
# 如果是從某個隊列添加的,則該隊列+1,之所以可以這樣是因爲基礎數變了,以醜數隊列爲基準
# 醜數隊列中總是最小的數*2,3,5得出的
indextwo +=1
if ugly[i] ==ugly[indexthree]*3:
indexthree +=1
if ugly[i] == ugly[indexfive]*5:
indexfive +=1
return ugly[index-1]
第一次只出現1次的字符
題目描述
在一個字符串(0<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符,並返回它的位置, 如果沒有則返回 -1(需要區分大小寫).(從0開始計數)
# -*- coding:utf-8 -*-
class Solution:
def FirstNotRepeatingChar(self, s):
# write code here
if len(s)==0:
return -1
if len(s)==1:
return 0
dic = {}
for i in s:
if i not in dic.keys():
dic[i] = 1
else:
dic[i] +=1
# 這裏注意字典是無序的
for index,i in enumerate(s):
if dic[i] ==1:
return index
return -1
數組中的逆序對
題目描述
在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007
輸入:1,2,3,4,5,6,7,0 輸出 :7
# -*- coding:utf-8 -*-
count = 0
#class Solution:
#def InversePairs(self, data):
# write code here
#if len(data)<=1:
#return 0
#count = 0
#for cur in range(len(data)-1,0,-1): # 當前數,從後向前
#for j in range(len(data)-len(data[cur:])):
#if data[j] > data[cur]:
#count +=1
#return count % 1000000007
#count = 0
class Solution:
def InversePairs(self, data):
global count
self.MergeSort(data)
return count%1000000007
def MergeSort(self,lists):
global count
if len(lists) <= 1:
return lists
num = int(len(lists)/2)
left = self.MergeSort(lists[:num])
right = self.MergeSort(lists[num:])
r, l=0, 0
result=[]
while l<len(left) and r<len(right):
if left[l] < right[r]:
result.append(left[l])
l += 1
else:
result.append(right[r])
r += 1
# 剩餘的左邊的數都大於右邊的那個數 所以加len(left)-l
count += len(left)-l
result += right[r:] # 這裏是某個數組過長
result += left[l:]
return result
兩個鏈表的第一個公共節點
題目描述
輸入兩個鏈表,找出它們的第一個公共結點。(注意因爲傳入數據是鏈表,所以錯誤測試數據的提示是用其他方式顯示的,保證傳入數據是正確的)
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
cur1 = pHead1
cur2 = pHead2
if cur1==None or cur2==None:
return None
while cur1!=cur2:
# ENTJ : 如果沒有公共點,兩個指針會同時到達null,然後跳出循環,不會死循環的
# 比較下一個
cur1 = cur1.next
cur2 = cur2.next
if cur1 != cur2:
# 這裏有個特殊情況,即二者有一方爲None的時候,鏈接兩個鏈表使其等長
# 這裏已經是next了,無需再寫cur.next
if cur1 == None: cur1 = pHead2
if cur2 == None: cur2 = pHead1
return cur1
數字在排序數組中出現的次數
題目描述
統計一個數字在排序數組中出現的次數。
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
# write code here
if len(data)==0 or k>data[-1]:
return 0
mid = 0
left =0
right =len(data)-1
count =0
while left<=right:
mid = int((left+right)/2)
if data[mid]<k:
# 中位數小於指定數字
left = mid+1
elif data[mid]>k:
right = mid-1
else:
break
# 找到了就向前向後找
if left <=right:
for i in range(mid,-1,-1):
if data[i] ==k:
count+=1
else:
# 找到第一個就別找了
break
for i in range(mid+1,len(data)):
if data[i]==k:
count +=1
else:
break
return count
二叉樹的深度
題目描述
輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度爲樹的深度。
# -*- 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 not pRoot:
# return 0
#left = self.TreeDepth(pRoot.left)
#right = self.TreeDepth(pRoot.right)
#res = left + 1 if left>right else right+1
#return res
# 下面使用層序遍歷
if not pRoot:
return 0
high = 0
queue = [pRoot]
while queue!= []:
childqueue = []
for node in queue:
if node.left:
childqueue.append(node.left)
if node.right:
childqueue.append(node.right)
queue = childqueue
high +=1
return high
平衡二叉樹
題目描述
輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。
注意:
在這裏,我們只需要考慮其平衡性,不需要考慮其是不是排序二叉樹
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def IsBalanced_Solution(self, pRoot):
# write code here
if not pRoot:
return True # 前提搞清楚空子樹是不是平衡二叉樹
left = self.depth(pRoot.left)
right = self.depth(pRoot.right)
#if (left-right) != (-1) or (left-right)!=1:
if abs(left - right) >1:
return False
return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
def depth(self,root):
if not root:
return 0
left = self.depth(root.right)
right = self.depth(root.left)
return max(left,right)+1
數組中只出現1次的數字
題目描述
一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。
# -*- coding:utf-8 -*-
class Solution:
# 返回[a,b] 其中ab是出現一次的兩個數字
def FindNumsAppearOnce(self, array):
# write code here
if len(array)<4:
return False
from collections import Counter
array1 =Counter(array)
res =[]
for key,value in array1.items():
if value ==1:
res.append(key)
return res
和爲S的連續正數序列
題目描述
小明很喜歡數學,有一天他在做數學作業時,要求計算出9~16的和,他馬上就寫出了正確答案是100。但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和爲100(至少包括兩個數)。沒多久,他就得到另一組連續正數和爲100的序列:18,19,20,21,22。現在把問題交給你,你能不能也很快的找出所有和爲S的連續正數序列? Good Luck!
輸出描述:
輸出所有和爲S的連續正數序列。序列內按照從小至大的順序,序列間按照開始數字從小到大的順序
# -*- coding:utf-8 -*-
class Solution:
def FindContinuousSequence(self, tsum):
# write code here
res = []
# 最大的兩個數應該是二分之一
for i in range(int(tsum/2)+1,0,-1):
# 末尾數
s = i
sequence = [i] # 用於存放單個序列
# 起始數從後向前
for j in range(i-1,0,-1):
# 向前遍歷
sequence.append(j)
s+=j
if s==tsum:
sequence = sorted(sequence)# 序列內排序
res.append(sequence)
break
if s>tsum:
break
# 下面進行序列間排序
res = sorted(res,key=lambda x:x[0])
# res = [[],[]]
return res
和爲S的兩個數字
題目描述
輸入一個遞增排序的數組和一個數字S,在數組中查找兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。
輸出描述:
對應每個測試案例,輸出兩個數,小的先輸出。
# -*- coding:utf-8 -*-
class Solution:
def FindNumbersWithSum(self, array, tsum):
# write code here
plow = 0
phigh =len(array)-1
res = []
if not array:
return []
if array[phigh-1]+array[phigh]<tsum:
return []
# 下面使用雙指針思想
while plow<phigh:
sequence = []
if array[plow]+array[phigh]==tsum:
sequence.append(array[plow])
sequence.append(array[phigh])
res.append(sequence)
plow +=1
phigh-=1
elif array[plow]+array[phigh]>tsum:
phigh-=1 #一側指針動
else:
plow+=1
# 輸出乘積最小的數
res = sorted(res,key = lambda x:x[0]*x[1])
# res=[[]]
return res[0] if res else []
左旋轉字符串
題目描述
彙編語言中有一種移位指令叫做循環左移(ROL),現在有個簡單的任務,就是用字符串模擬這個指令的運算結果。對於一個給定的字符序列S,請你把其循環左移K位後的序列輸出。例如,字符序列S=”abcXYZdef”,要求輸出循環左移3位後的結果,即“XYZdefabc”。是不是很簡單?OK,搞定它!
# -*- coding:utf-8 -*-
class Solution:
def LeftRotateString(self, s, n):
# write code here
if n >len(s):
return ""
if not s:
return ""
sp1,sp2 = s[:n],s[n:]
res = sp2+sp1
return res
翻轉單詞順序列
題目描述
牛客最近來了一個新員工Fish,每天早晨總是會拿着一本英文雜誌,寫些句子在本子上。同事Cat對Fish寫的內容頗感興趣,有一天他向Fish借來翻看,但卻讀不懂它的意思。例如,“student. a am I”。後來才意識到,這傢伙原來把句子單詞的順序翻轉了,正確的句子應該是“I am a student.”。Cat對一一的翻轉這些單詞順序可不在行,你能幫助他麼?
# -*- coding:utf-8 -*-
class Solution:
def ReverseSentence(self, s):
# write code here
s_lis = s.split(' ')
s_lis.reverse() #這裏注意返回的是一個None,是對原有序列的改變
res = ' '.join(x for x in s_lis)
return res
撲克牌順子
題目描述
LL今天心情特別好,因爲他去買了一副撲克牌,發現裏面居然有2個大王,2個小王(一副牌原本是54張^_^)...他隨機從中抽出了5張牌,想測測自己的手氣,看看能不能抽到順子,如果抽到的話,他決定去買體育彩票,嘿嘿!!“紅心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是順子.....LL不高興了,他想了想,決定大\小 王可以看成任何數字,並且A看作1,J爲11,Q爲12,K爲13。上面的5張牌就可以變成“1,2,3,4,5”(大小王分別看作2和4),“So Lucky!”。LL決定去買體育彩票啦。 現在,要求你使用這幅牌模擬上面的過程,然後告訴我們LL的運氣如何, 如果牌能組成順子就輸出true,否則就輸出false。爲了方便起見,你可以認爲大小王是0。
# -*- coding:utf-8 -*-
class Solution:
def IsContinuous(self, numbers):
# write code here
if numbers ==[]:
return False
dic = {
'J':11,
'Q':12,
'K':13,
'A':1
}
# 進行異常值替換
for number in numbers:
if number in dic.keys():
number = dic[number]
# 下面檢查是不是順子
count = 0 #統計爲王的數量
cz = [] # 統計差值
numbers.sort()
for i in range(5):
if numbers[i]==0:
count +=1
if count==4:
return True
# 存入差值
for i in range(count,4):
cz.append(numbers[i+1]-numbers[i])
for i in cz:
if i==0:
return False
if i ==1:
continue
if i >1:
count =count -(i-1)
if count !=0:
return False
return True
孩子們的遊戲
題目描述
每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。HF作爲牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的:首先,讓小朋友們圍成一個大圈。然後,他隨機指定一個數m,讓編號爲0的小朋友開始報數。每次喊到m-1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮物,並且不再回到圈中,從他的下一個小朋友開始,繼續0...m-1報數....這樣下去....直到剩下最後一個小朋友,可以不用表演,並且拿到牛客名貴的“名偵探柯南”典藏版(名額有限哦!!^_^)。請你試着想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)
注意:
如果沒有小朋友,請返回-1
# -*- coding:utf-8 -*-
class Solution:
def LastRemaining_Solution(self, n, m):
# write code here
if n<1:
return -1
n_child = [i for i in range(n)]
while len(n_child) >1:
gift_child = (m-1)%len(n_child)
# 取完禮物就走,根據索引刪除,這裏不對,不是從0重頭唱歌,而是下一位接着唱
n_child.pop(gift_child)
# 保證下一次唱歌的爲列表開頭
n_child = n_child[gift_child:]+n_child[:gift_child]
return n_child[0]
求1+2+。。。n
題目描述
求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。
# -*- coding:utf-8 -*-
class Solution:
def Sum_Solution(self, n):
# write code here
return sum(range(n+1))
不用加減乘除做加法
題目描述
寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。
# -*- coding:utf-8 -*-
class Solution:
def Add(self, num1, num2):
# write code here
MAX = 0x7fffffff # 最大整數
mask = 0xffffffff # 求補碼
while num2 != 0: # 直到無進位
num1, num2 = (num1 ^ num2), ((num1 & num2) << 1)
num1 = num1 & mask #數
num2 = num2 & mask # 進位
return num1 if num1 <= MAX else ~(num1 ^ mask)
把字符串轉換成整數
題目描述
將一個字符串轉換成一個整數,要求不能使用字符串轉換整數的庫函數。 數值爲0或者字符串不是一個合法的數值則返回0
輸入描述:
輸入一個字符串,包括數字字母符號,可以爲空
+2147483647 1a33
輸出描述:
如果是合法的數值表達則返回該數字,否則返回0
# -*- coding:utf-8 -*-
class Solution:
def StrToInt(self, s):
# write code here
if s =='':
return 0
numList = ['0','1','2','3','4','5','6','7','8','9'] # 數字和index要相對應
flag = 1
if s[0] == '+' and len(s)>1: # 先解決符號問題
flag = 1
s = s[1:]
if s[0] == '-' and len(s)>1:
flag = -1
s = s[1:]
# 下面進行求和
sum1 = 0
for i in s:
if i in numList:
sum1 = sum1*10+ numList.index(i)
else:
return 0
return flag*sum1
數組中重複的數字
題目描述
在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內。 數組中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出數組中任意一個重複的數字。 例如,如果輸入長度爲7的數組{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字2。
# -*- coding:utf-8 -*-
class Solution:
# 這裏要特別注意~找到任意重複的一個值並賦值到duplication[0]
# 函數返回True/False
def duplicate(self, numbers, duplication):
# write code here
from collections import Counter
count = dict(Counter(numbers))
for key ,value in count.items():
if value > 1:
duplication[0] =key
return True
return False
構建乘積數組
題目描述
給定一個數組A[0,1,...,n-1],請構建一個數組B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。(注意:規定B[0] = A[1] * A[2] * ... * A[n-1],B[n-1] = A[0] * A[1] * ... * A[n-2];)
# -*- coding:utf-8 -*-
class Solution:
def multiply(self, A):
# write code here
if not A:
return []
# 題目的意思是B[n] = B[n-1]*A[n-1]*A[i+1]...A[n-1],少了A[i]那一項的乘積
# 不要看注意內容,太容易帶偏
B = [1]*len(A)
# 將B做切割,先看A[i-1]部分,記得i>=0
for i in range(1,len(A)):
B[i] = B[i-1]*A[i-1]
# 下面看後面,當i = n-1時候,沒有後面,n-2時候*A[n-1],n-3時候*A[n-2]*A[n-1]
tmp = 1 # 暫存乘積結果
for i in range(len(A)-2,-1,-1):
tmp = tmp*A[i+1]
B[i] = B[i]*tmp
return B
# B[1]=A[0];B[2]=A[0]*A[1]
#if len(A)<=0:
# return None
#B = [1] *len(A)
#if len(A)==1:
# B = A
# return B
#for i in A:
# B[0] =B[0]*i
# for i in range(1,len(B)):
# for j in range(i):
# B[i] = B[i]*A[j]
# return B
#這題和我想的不一樣啊,我覺得題目有問題
正則表達匹配
題目描述
請實現一個函數用來匹配包括'.'和'*'的正則表達式。模式中的字符'.'表示任意一個字符,而'*'表示它前面的字符可以出現任意次(包含0次)。 在本題中,匹配是指字符串的所有字符匹配整個模式。例如,字符串"aaa"與模式"a.a"和"ab*ac*a"匹配,但是與"aa.a"和"ab*a"均不匹配
# -*- coding:utf-8 -*-
class Solution:
# s, pattern都是字符串
def match(self, s, pattern):
# write code here
if len(s)==0 and len(pattern)==0:
return True
elif len(s)!=0 and len(pattern)==0:
return False
elif len(s)==0 and len(pattern)!=0:
if len(pattern)>1 and pattern[1]=='*':
# 因爲s爲空
return self.match(s,pattern[2:])
else:
return False
else:
# pattern 第二個字符爲*
if len(pattern)>1 and pattern[1] =='*':
# s與pattern首位不同
if s[0]!=pattern[0] and pattern[0]!='.':
return self.match(s,pattern[2:])
else:
# pattern中*爲空;pattern中*爲1;【s後移1個,*可以多位匹配】
return self.match(s,pattern[2:]) or self.match(s[1:],pattern[2:]) or self.match(s[1:],pattern)
else:
if s[0]==pattern[0] or pattern[0]=='.':
return self.match(s[1:],pattern[1:])
else:
return False
表示數值的字符串
題目描述
請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示數值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
# -*- coding:utf-8 -*-
class Solution:
def isNumeric(self, s):
# write code here
import re
pattern = '[+-]?[0-9]*([.][0-9]*)?([eE][+-]?[0-9]+)?'
return True if re.match(pattern,s).group() == s else False
字符流中第一個不重複的字符
題目描述
請實現一個函數用來找出字符流中第一個只出現一次的字符。例如,當從字符流中只讀出前兩個字符"go"時,第一個只出現一次的字符是"g"。當從該字符流中讀出前六個字符“google"時,第一個只出現一次的字符是"l"。
輸出描述:
如果當前字符流沒有存在出現一次的字符,返回#字符。
# -*- coding:utf-8 -*-
class Solution:
# 返回對應char
s = ''
def FirstAppearingOnce(self):
# write code here
from collections import Counter
count = Counter(self.s)
for i in self.s:
if count[i] ==1:
return i
return '#'
def Insert(self, char):
# write code here
self.s += char
鏈表中環的入口節點
題目描述
給一個鏈表,若其中包含環,請找出該鏈表的環的入口結點,否則,輸出null。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
fast = pHead
low = pHead
while(fast!=None and fast.next!=None):
fast = fast.next.next
low = low.next
if fast ==low:
break
# 根據上面的退出條件寫一下!!!
if fast==None or fast.next ==None:
return None
low = pHead
while fast!=low:
fast = fast.next
low = low.next
return low
刪除鏈表中重複的節點
題目描述
在一個排序的鏈表中,存在重複的結點,請刪除該鏈表中重複的結點,重複的結點不保留,返回鏈表頭指針。 例如,鏈表1->2->3->3->4->4->5 處理後爲 1->2->5
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteDuplication(self, pHead):
# write code here
if not pHead:
return None
pPreNode = None #先前鏈接節點
pNode = pHead #遍歷節點
while pNode:
pNext = pNode.next
needDelete = False
# 判斷是否相等
if pNext and pNode.val ==pNext.val:
needDelete = True
if not needDelete:
# 如果沒有重複
pPreNode = pNode
pNode = pNext
else:
#核心如果有重複
deleteVal = pNode.val
deleteNode = pNode #需要把源節點一起刪除
# 刪除操作
while deleteNode and deleteNode.val ==deleteVal:
pNext = deleteNode.next #保存後一個節點
del deleteNode # 刪除操作
deleteNode = pNext #刪除後移
if not pPreNode:
#如果連頭結點都刪掉了
pHead = pNext # 就從下一個節點開始
else:
pPreNode.next = pNext
pNode = pNext # 從該節點開始遍歷
return pHead
二叉樹的下一個節點
題目描述
給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指針。
# -*- coding:utf-8 -*-
# class TreeLinkNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
# self.next = None
class Solution:
def GetNext(self, pNode):
# write code her
if not pNode:
return None
if pNode.right:
# 存在右子樹
pNode = pNode.right
while pNode.left:
pNode = pNode.left
return pNode
# 如果不存在右子樹,檢查其是否是父節點的左孩子
while pNode.next:
pRoot = pNode.next #指向父節點
if pRoot.left == pNode:
return pRoot
else:
pNode = pNode.next # 一直尋找父節點,直至當前節點爲父節點的左孩子
return None # 沒找到的話
對稱的二叉樹
題目描述
請實現一個函數,用來判斷一顆二叉樹是不是對稱的。注意,如果一個二叉樹同此二叉樹的鏡像是同樣的,定義其爲對稱的。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetrical(self, pRoot):
# write code here
# 這題使用遞歸
if not pRoot:
return True
return self.issymmer(pRoot.left,pRoot.right)
def issymmer(self,left,right):
if not left and not right:
return True
if not left or not right:
return False
# 值相等且鏡像位置的子樹相等
return left.val == right.val and self.issymmer(left.left,right.right) and self.issymmer(left.right,right.left)
按之字形順序打印二叉樹
題目描述
請實現一個函數按照之字形打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右至左的順序打印,第三行按照從左到右的順序打印,其他行以此類推。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def Print(self, pRoot):
# write code here
if not pRoot:
return [] # 一般不要輕易返回None值
queue = [pRoot]
result = []
# 先層序遍歷存進去再說,但稍微不同的是存列表
while queue:
res = []
nextqueue = []
for i in queue:
res.append(i.val)
if i.left:
nextqueue.append(i.left)
if i.right:
nextqueue.append(i.right)
queue = nextqueue
result.append(res)
for i in range(len(result)):
if i %2!=0:
# 逆序
result[i].reverse() # 這個是對源數據進行反向,不會返回數據,注意reversed返回的是個迭代器
return result
把二叉樹打印成多行
題目描述
從上到下按層打印二叉樹,同一層結點從左至右輸出。每一層輸出一行。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回二維列表[[1,2],[4,5]]
def Print(self, pRoot):
# write code here
if not pRoot:
return []
result =[]
queue = [pRoot]
while queue:
res = []
nextqueue = []
for i in queue:
res.append(i.val)
if i.left:
nextqueue.append(i.left)
if i.right:
nextqueue.append(i.right)
queue = nextqueue
result.append(res)
return result
序列化二叉樹
題目描述
請實現兩個函數,分別用來序列化和反序列化二叉樹
注意:
二叉樹的序列化是指:把一棵二叉樹按照某種遍歷方式的結果以某種格式保存爲字符串,從而使得內存中建立起來的二叉樹可以持久保存。序列化可以基於先序、中序、後序、層序的二叉樹遍歷方式來進行修改,序列化的結果是一個字符串,序列化時通過 某種符號表示空節點(#),以 ! 表示一個結點值的結束(value!)。
二叉樹的反序列化是指:根據某種遍歷順序得到的序列化字符串結果str,重構二叉樹。
舉例:例如,我們可以把一個只有根節點爲1的二叉樹序列化爲"1,",然後通過自己的函數來解析回這個二叉樹
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
flag = -1 # s標識位
def Serialize(self, root):
# write code here
if not root:
return '#'
# 前序遍歷
return str(root.val) + ','+ self.Serialize(root.left) +','+ self.Serialize(root.right)
def Deserialize(self, s):
# write code here
self.flag +=1 #一定要加self
lis = s.split(',')
if self.flag >=len(s):
# 當指針超過s時
return None
root = None # 設置一個節點
if lis[self.flag]!= '#':
root = TreeNode(int(lis[self.flag])) # 注意TreeNOde傳入的是一個值
root.left = self.Deserialize(s)
root.right = self.Deserialize(s)
return root
二叉搜索樹的第K的節點
題目描述
給定一棵二叉搜索樹,請找出其中的第k小的結點。例如, (5,3,7,2,4,6,8) 中,按結點數值大小順序第三小結點的值爲4。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回對應節點TreeNode
def __init__(self):
self.result = []
def KthNode(self, pRoot, k):
# write code here
# 中序遍歷會得到從小到大的順序
#strr = self.KthNode(pRoot.left)+str(pRoot.val)+self.KthNode(pRoot.right)
#global result
#result = [] # 不能設在函數之外
self.Zhongxu(pRoot)
if k<=0 or len(self.result)<k: # 如果超過strr範圍,k<=0一般放前面
return None
return self.result[k-1]
def Zhongxu(self,pRoot):
if not pRoot:
return None
self.Zhongxu(pRoot.left)
self.result.append(pRoot)
self.Zhongxu(pRoot.right)
數據流中的中位數
題目描述
如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從數據流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用Insert()方法讀取數據流,使用GetMedian()方法獲取當前讀取數據的中位數。
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.lis = []
self.count = 0
def Insert(self, num):
# write code here
self.lis.append(num)
self.count +=1
def GetMedian(self,n=None):
# write code here
self.lis = sorted(self.lis)
if self.count == 0:
return 0
if self.count%2!=0:
return self.lis[int(self.count/2)]
else:
return (self.lis[self.count/2]+self.lis[self.count/2 -1])/2.0
滑動窗口的最大值
題目描述
給定一個數組和滑動窗口的大小,找出所有滑動窗口裏數值的最大值。例如,如果輸入數組{2,3,4,2,6,2,5,1}及滑動窗口的大小3,那麼一共存在6個滑動窗口,他們的最大值分別爲{4,4,6,6,6,5}; 針對數組{2,3,4,2,6,2,5,1}的滑動窗口有以下6個: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
# -*- coding:utf-8 -*-
class Solution:
def maxInWindows(self, num, size):
# write code here
# 存在len(num)-size+1個滑動窗口
if size>len(num):
return []
if size<=0:
return []
maxlis = []
for i in range(len(num)-size+1):
# 滑動窗口可以看做切片
slic = num[i:i+size]
maxlis.append(max(slic))
return maxlis
矩陣中的路徑
題目描述
請設計一個函數,用來判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向左,向右,向上,向下移動一個格子。如果一條路徑經過了矩陣中的某一個格子,則該路徑不能再進入該格子。 例如
矩陣中包含一條字符串"bcced"的路徑,但是矩陣中不包含"abcb"路徑,因爲字符串的第一個字符b佔據了矩陣中的第一行第二個格子之後,路徑不能再次進入該格子。
# -*- coding:utf-8 -*-
class Solution:
def hasPath(self, matrix, rows, cols, path):
# write code here
# 標誌位
flag = [False]*rows*cols
for i in range(rows):
for j in range(cols):
# 找起始點
# 爲什麼不一樣??
if self.judge(list(matrix),rows,cols,path,i,j,0,flag):
# 一維數組來判斷,k是path起始位
return True
return False
def judge(self,matrix,rows,cols,path,i,j,k,flag):
index = i*cols+j #標誌位
# 遞歸終止條件
if i<0 or j<0 or i>=rows or j>=cols or matrix[index]!=path[k] or flag[index] ==True:
return False
if k == len(path)-1:
return True
# 首標誌位爲True
flag[index] = True
# 判斷是否能走
if self.judge(matrix,rows,cols,path,i-1,j,k+1,flag) or self.judge(matrix,rows,cols,path,i+1,j,k+1,flag) or self.judge(matrix,rows,cols,path,i,j-1,k+1,flag) or self.judge(matrix,rows,cols,path,i,j+1,k+1,flag):
return True
flag[index] = False # 不通則還原標誌位
return False
機器人的運動範圍
題目描述
地上有一個m行和n列的方格。一個機器人從座標0,0的格子開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數位之和大於k的格子。 例如,當k爲18時,機器人能夠進入方格(35,37),因爲3+5+3+7 = 18。但是,它不能進入方格(35,38),因爲3+5+3+8 = 19。請問該機器人能夠達到多少個格子?
# -*- coding:utf-8 -*-
class Solution:
#def movingCount(self, threshold, rows, cols):
# write code here
# count = rows*cols # 假設一開始全能到達
#for i in range(rows):
# for j in range(cols):
# if self.chai(i) + self.chai(j) > threshold:
# count -=1
# return count
#def chai(self,number):
# # 這個作用是對數字進行拆分,並返回其和
# summ = 0
# lis = map(int,list(str(number)))
# summ = sum(lis)
# return summ
def __init__(self):
self.count = 0
def movingCount(self, threshold, rows, cols):
arr = [[1 for _ in range(cols)] for _ in range(rows)]
self.findway(0,0,threshold,arr) # 如果能到達則設爲1
return self.count
def findway(self,i,j,threshold,arr):
# 遞歸停止條件
if i<0 or j<0 or i>=len(arr) or j >=len(arr[0]):
return
lis1 = list(map(int,list(str(i)))) # 字符串變數字的優化解法
lis2 = list(map(int,list(str(j))))
sum1 = sum(lis1)
sum2 = sum(lis2)
if sum1 +sum2>threshold or arr[i][j]!=1:
return
# 如果可以走
self.count +=1
arr[i][j] = 0
# 下面就是繼續走的遞歸了
self.findway(i+1,j,threshold,arr)
self.findway(i-1,j,threshold,arr)
self.findway(i,j+1,threshold,arr)
self.findway(i,j-1,threshold,arr)
剪繩子
題目描述
給你一根長度爲n的繩子,請把繩子剪成整數長的m段(m、n都是整數,n>1並且m>1),每段繩子的長度記爲k[0],k[1],...,k[m]。請問k[0]xk[1]x...xk[m]可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別爲2、3、3的三段,此時得到的最大乘積是18。
輸入描述:
輸入一個數n,意義見題面。(2 <= n <= 60) 8
輸出描述:
輸出答案。18
# -*- coding:utf-8 -*-
class Solution:
def cutRope(self, number):
# write code here
# 這題可以用貪婪,但我選擇動態規劃
if number <=1:
return 0
if number==2:
return 1
if number ==3:
return 2
# 下面是number>=4的情況
space = [0]* (number+1) # 輔助空間需要包含0
space[0] = 0
space[1] = 1
space[2] = 2
space[3] = 3 #這裏f(x) = max(f(x-i)*f(i)),這裏兩個子部分可以不切,所以和上面值不同
for i in range(4,number+1):
maxx = 0 # 用於記錄每一個f(i)的最大值
for j in range(i/2+1): # 這裏是對f(i)的切分,本質還是max(f(x-i)*f(i))
maxx = max(maxx,space[j]*space[i-j])
space[i] = maxx
return space[number]