python 刷剑指offer
编程环境python2,OJ:牛客
1.二维数组中的查找
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
if len(array)==0 or len(array[0])==0:
return False
i = 0
j = len(array[0])-1
while(i<len(array) and j>=0):
if array[i][j]==target:
return True
elif array[i][j]>target:
j-=1
else:
i+=1
return False
2.替换空格
class Solution:
# s 源字符串
def replaceSpace(self, s):
#def replaceSpaceByAppend(self, s):
if s == None:
return None
if len(s) == 0:
return ''
result = ''
for item in s:
if item.isspace():
result = result+'%20'
else:
result = result+item
return result
3.从头到尾打印链表
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
4.重建二叉树
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
if pre==[]:
return None
val = pre[0]
idx = tin.index(val)
ltin = tin[0:idx]
rtin = tin[idx+1:]
lpre = pre[1:1+len(ltin)]
rpre = pre[1+len(ltin):]
root = TreeNode(val)
root.left = self.reConstructBinaryTree(lpre,ltin)
root.right = self.reConstructBinaryTree(rpre,rtin)
return root
5.用两个栈实现队列
class Solution:
def __init__(self):
self.stack1 = []
self.stack2 = []
def push(self, node):
# write code here
self.stack1.append(node)
def pop(self):
# return xx
if len(self.stack2):
return self.stack2.pop()
while(self.stack1):
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
6.旋转数组的最小数字
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if rotateArray == []:
return 0
_len = len(rotateArray)
left = 0
right = _len -1
while left <= right:
mid = int((left + right) >> 1)
if rotateArray[mid] < rotateArray[mid - 1]:
return rotateArray[mid]
if rotateArray[mid] >= rotateArray[right]:
left = mid + 1
else:
right = mid - 1
return rotateArray[mid]
7.斐波那契数列
class Solution:
def Fibonacci(self, n):
# write code here
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]
8.跳台阶
class Solution:
def jumpFloor(self, number):
# write code here
if number == 0:
return 0
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]
9.变态跳台阶
class Solution:
def jumpFloorII(self, number):
# write code here
if number == 0:
return 0
if number == 1 or number ==2:
return number
ret = sum = 3
for i in range(number -2):
ret = sum + 1
sum += ret
return ret
10.矩形覆盖
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]
11.二进制中1的个数
class Solution:
def NumberOf1(self, n):
# write code here
ans = 0
if n<0:
n = n & 0xffffffff
while n:
ans += n & 1
n >>= 1
return ans
12.数值的整数次方
class Solution:
def Power(self, base, exponent):
# write code here
if exponent == 0:
return 1
ans = pos = exp = 1
if exponent < 0:
pos = -1
exponent = -exponent
while exponent:
if exponent % 2:
ans = ans *(base ** (exp))
exponent = exponent >> 1
exp = exp*2
return ans if pos==1 else 1.0/ans
13.调整数组顺序使奇数位于偶数前面
class Solution:
def reOrderArray(self, array):
# write code here
result = []
odd = [item for item in array if item%2]
even = [item for item in array if not (item%2)]
result = odd + even
return result
14.链表中倒数第K个节点
class Solution:
def FindKthToTail(self, head, k):
# write code here
if head == None or k <= 0:
return None
p1 = p2 = head
while k>1:
if p1.next != None:
p1 = p1.next
k -= 1
else:
return None
while p1.next != None:
p2 = p2.next
p1 = p1.next
return p2
15.反转链表
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
pReversedHead = None
pNode = pHead
pPrve = None
while pNode != None:
pNext = pNode.next
if pNext == None:
pReversedHead = pNode
pNode.next = pPrve
pPrve = pNode
pNode = pNext
return pReversedHead
16.合并两个有序链表
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
# write code here
if pHead1 == None:
return pHead2
if pHead2 == None:
return pHead1
pMergeHead = None
if pHead1.val < pHead2.val:
pMergeHead = pHead1
pMergeHead.next = self.Merge(pHead1.next,pHead2)
else:
pMergeHead = pHead2
pMergeHead.next = self.Merge(pHead1,pHead2.next)
return pMergeHead
17.树的子结构
class Solution:
def HasSubtree(self, pRoot1, pRoot2):
# write code here
def subtree(pRoot1,pRoot2):
if pRoot2 == None and pRoot1 == None:
return True
if pRoot2 == None:
return False
if pRoot1 == None:
return False
if pRoot2.val == pRoot1.val:
if pRoot2.left == None and pRoot2.right == None:
return True
if subtree(pRoot1.left,pRoot2.left) and subtree(pRoot1.right,pRoot2.right):
return True
return subtree(pRoot1.left,pRoot2) or subtree(pRoot1.right,pRoot2)
if pRoot1 == None and pRoot2 == None:
return False
return subtree(pRoot1,pRoot2)
18.二叉树的镜像
class Solution:
# 返回镜像树的根节点
def Mirror(self, root):
# write code here
if root == None:
return
if root.left == None and root.right == None:
return root
self.Mirror(root.left)
self.Mirror(root.right)
root.left,root.right = root.right,root.left
19.顺时针打印矩阵
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
printArr = []
if matrix == None:
return
if matrix == []:
return []
start = 0 # 每次循环时起始点
rows = len(matrix) # 列数
columns = len(matrix[0]) # 行数
while columns > 2 * start and rows > 2 * start:
endX = columns - 1 - start
endY = rows - 1 - start
# 从左到右将数字存入printArr
for i in range(start, endX+1):
number = matrix[start][i]
printArr.append(number)
# 从上到下将数字存入printArr
if start < endY:
for i in range(start+1, endY+1):
number = matrix[i][endX]
printArr.append(number)
# 从右到左将数字存入printArr
if start < endX and start < endY:
for i in range(endX-1, start-1, -1):
number = matrix[endY][i]
printArr.append(number)
# 从下到上将数字存入printArr
if start < endX and start < endY-1:
for i in range(endY-1, start, -1):
number = matrix[i][start]
printArr.append(number)
start += 1
return printArr
20.包含min函数的栈
class Solution:
def __init__(self):
self.Stack = []
self.minStack = []
def push(self, node):
# write code here
self.Stack.append(node)
if self.minStack == [] or node < self.min():
self.minStack.append(node)
else:
tmp = self.min()
self.minStack.append(tmp)
def pop(self):
# write code here
if self.Stack == [] or self.minStack == []:
return None
self.Stack.pop()
self.minStack.pop()
def top(self):
# write code here
return self.Stack[-1]
def min(self):
# write code here
return self.minStack[-1]l
21.栈的压入、弹出序列
class Solution:
def IsPopOrder(self, pushV, popV):
# write code here
if pushV == [] or popV == []:
return False
stack = []
for i in pushV:
stack.append(i)
if stack[-1] != popV[0]:
continue
else:
stack.pop()
popV.pop(0)
while len(stack) > 0 and stack[-1] == popV[0]:
stack.pop()
popV.pop(0)
if len(stack) == 0:
return True
else:
return False
22.从上到下打印二叉树
class Solution:
# 返回从上到下每个节点值列表,例:[1,2,3]
def PrintFromTopToBottom(self, root):
# write code here
queue = []
if not root:
return []
result = []
queue.append(root)
while len(queue) > 0:
correntRoot = queue.pop(0)
result.append(correntRoot.val)
if correntRoot.left:
queue.append(correntRoot.left)
if correntRoot.right:
queue.append(correntRoot.right)
return result
23.二叉树的后续遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
class Solution:
def VerifySquenceOfBST(self, sequence):
# write code here
if sequence == []:
return False
root = sequence[-1]
length = len(sequence)
index = 0
for i in range(length-1):
index = i
if sequence[i] > root:
break
for j in range(index+1,length-1):
if sequence[j] < root:
return False
left = True
if index > 0:
left = self.VerifySquenceOfBST(sequence[:index])
right = True
if index < length-1:
right = self.VerifySquenceOfBST(sequence[index:length-1])
return left and right
24.二叉树中和为某一值得路径
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
class Solution:
# 返回二维列表,内部每个列表表示找到的路径
def FindPath(self, root, expectNumber):
# write code here
if not root:
return []
if root.left == None and root.right == None:
if expectNumber == root.val:
return [[root.val]]
else:
return []
a = self.FindPath(root.left, expectNumber - root.val) + self.FindPath(root.right, expectNumber - root.val)
return [[root.val] + i for i in a]
25.复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
if pHead == None:
return None
self.CloneNodes(pHead)
self.ConnectRandomNodes(pHead)
return self.ReconnectNodes(pHead)
# 复制原始链表的每个结点, 将复制的结点链接在其原始结点的后面
def CloneNodes(self, pHead):
pNode = pHead
while pNode:
pCloned = RandomListNode(0) #不能直接赋值pNode,不然会循环重复
pCloned.label = pNode.label
pCloned.next = pNode.next
# pCloned.random = None #不需要写这句话, 因为创建新的结点的时候,random自动指向None
pNode.next = pCloned
pNode = pCloned.next
# 将复制后的链表中的复制结点的random指针链接到被复制结点random指针的后一个结点
def ConnectRandomNodes(self, pHead):
pNode = pHead
while pNode:
pCloned = pNode.next
if pNode.random != None:
pCloned.random = pNode.random.next
pNode = pCloned.next
# 拆分链表, 将原始链表的结点组成新的链表, 复制结点组成复制后的链表
def ReconnectNodes(self, pHead):
pNode = pHead
pClonedHead = pClonedNode = pNode.next
pNode.next = pClonedHead.next
pNode = pNode.next
while pNode:
pClonedNode.next = pNode.next
pClonedNode = pClonedNode.next
pNode.next = pClonedNode.next
pNode = pNode.next
return pClonedHead
26.二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
class Solution:
def Convert(self, pRootOfTree):
# write code here
if pRootOfTree == None:
return None
if not pRootOfTree.left and not pRootOfTree.right:
return pRootOfTree
#处理左子树
self.Convert(pRootOfTree.left)
left = pRootOfTree.left
if left:
while left.right:
left = left.right
pRootOfTree.left, left.right = left, pRootOfTree
#处理右子树
self.Convert(pRootOfTree.right)
right = pRootOfTree.right
if right:
while right.left:
right = right.left
pRootOfTree.right, right.left = right, pRootOfTree
while pRootOfTree.left:
pRootOfTree = pRootOfTree.left
return pRootOfTree
27.字符串的排列
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
class Solution:
def Permutation(self, ss):
# write code here
if not len(ss):
return []
if len(ss) == 1:
return list(ss)
charList = list(ss)
charList.sort()
pStr = []
for i in range(len(charList)):
if i > 0 and charList[i] == charList[i-1]:
continue
temp = self.Permutation(''.join(charList[:i])+''.join(charList[i+1:]))
for j in temp:
pStr.append(charList[i]+j)
return pStr
28.数组中出现次数超过一般的数字
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
if not numbers:
return 0
num = numbers[0]
count = 1
for i in range(1, len(numbers)):
if numbers[i] == num:
count += 1
else:
count -= 1
if count == 0:
num = numbers[i]
count = 1
count = 0
for i in numbers:
if i == num:
count += 1
return num if count > len(numbers) / 2.0 else 0
29.最小的k个数
class Solution:
def GetLeastNumbers_Solution(self, tinput, k):
# write code here
import heapq
heaps = []
ret = []
for num in tinput:
heapq.heappush(heaps,num)
if k>len(heaps):
return []
for i in range(k):
ret.append(heapq.heappop(heaps))
return ret
30.连续子数组的最大和
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
class Solution:
def FindGreatestSumOfSubArray(self, array):
# write code here
if len(array) <= 0 or array == []:
return 0
nSubSum = 0
nGreatSum = array[0]
for i in range(len(array)):
if nSubSum < 0:
nSubSum = array[i]
else:
nSubSum += array[i]
if nSubSum >= nGreatSum:
nGreatSum = nSubSum
return nGreatSum
31.整数中1出现的次数(从1到n整数中1出现的次数)
class Solution:
def NumberOf1Between1AndN_Solution(self, n):
# write code here
if n<1: return 0
if n==1: return 1
last,ans,pos = 0,0,1
while(n):
num = n%10
n = n/10
ans += pos*n
if num>1:
ans+=pos
elif num==1:
ans+=(last+1)
last = last+num*pos
pos*=10
return ans
32.把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
class Solution:
def PrintMinNumber(self, numbers):
# write code here
if numbers == None or len(numbers) <= 0:
return ""
A = ["" for i in range(len(numbers))]
for i in range(len(numbers)):
A[i] = str(numbers[i])
A.sort(self.cmp)
return "".join(A)
def cmp(self,e1,e2):
s1 = e1 +e2
s2 = e2 +e1
return cmp(s1,s2)
33.丑数
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
class Solution:
def GetUglyNumber_Solution(self, index):
# write code here
import heapq
if index<1:
return 0
heaps = []
heapq.heappush(heaps,1)
lastnum = None
idx = 1
while(idx<=index):
curnum = heapq.heappop(heaps)
while(curnum == lastnum):
curnum = heapq.heappop(heaps)
lastnum = curnum
idx += 1
heapq.heappush(heaps,curnum*2)
heapq.heappush(heaps,curnum*3)
heapq.heappush(heaps,curnum*5)
return lastnum
34.第一个只出现一次的字符
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).
class Solution:
def FirstNotRepeatingChar(self, s):
# write code here
queue = []
memories = dict()
for idx,char in enumerate(s):
if char not in memories:
queue.append(idx)
memories[char]=0
memories[char]+=1
while(queue and memories[s[queue[0]]]>1):
queue.pop(0)
return queue[0] if queue else -1
35.数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
class Solution:
def InversePairs(self, data):
# write code here
if len(data)<=0:
return 0
copy = []
for i in range(len(data)):
copy.append(data[i])
copy.sort()
count = 0
i = 0
while len(copy)>i:
count += data.index(copy[i])
data.remove(copy[i])
i +=1
return count
36.两个链表的第一个公共节点
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
nLength1 = self.GetListLength(pHead1)
nLength2 = self.GetListLength(pHead2)
nLengthDiff = abs(nLength1 - nLength2)
if nLength1 > nLength2:
pListHeadLong = pHead1
pListHeadShort = pHead2
else:
pListHeadLong = pHead2
pListHeadShort = pHead1
for i in range(nLengthDiff):
pListHeadLong = pListHeadLong.next
while pListHeadLong != None and pListHeadShort != None and pListHeadLong != pListHeadShort:
pListHeadLong = pListHeadLong.next
pListHeadShort = pListHeadShort.next
pFirstCommonNode = pListHeadLong
return pFirstCommonNode
def GetListLength(self, pHead):
nLength = 0
while pHead != None:
pHead = pHead.next
nLength += 1
return nLength
37.数字在排序数组中出现的个数
class Solution:
def GetNumberOfK(self, data, k):
# write code here
numbers = 0
if data != None and len(data)>0:
length = len(data)
first = self.GetFirstK(data, length, k, 0, length-1)
last = self.GetLastK(data, length, k, 0, length-1)
if first > -1:
numbers = last - first +1
return numbers
def GetFirstK(self, data, length, k, start, end):
if start > end:
return -1
midindex = (start + end)//2
middata = data[midindex]
if middata == k:
if midindex >0 and data[midindex -1] == k:
end = midindex -1
else:
return midindex
elif middata > k:
end = midindex - 1
else:
start = midindex + 1
return self.GetFirstK(data, length, k, start, end)
def GetLastK(self, data, length, k, start, end):
if start > end:
return -1
midindex = (start + end)//2
middata = data[midindex]
if middata == k:
if midindex < end and data[midindex +1] == k:
start = midindex +1
else:
return midindex
elif middata > k:
end = midindex - 1
else:
start = midindex + 1
return self.GetLastK(data, length, k, start, end)
38.二叉树的深度
class Solution:
def TreeDepth(self, pRoot):
# write code here
if pRoot == None:
return 0
else:
return max(self.TreeDepth(pRoot.left),self.TreeDepth(pRoot.right)) + 1
39.平衡二叉树
class Solution:
def IsBalanced_Solution(self, pRoot):
# write code here
if pRoot == None:
return True
if abs(self.getDepth(pRoot.left) - self.getDepth(pRoot.right)) > 1:
return False
else:
return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
def getDepth(self,pRoot):
if pRoot == None:
return 0
return max(self.getDepth(pRoot.left),self.getDepth(pRoot.right)) + 1
40.数组中只出现一次的数字
class Solution:
# 返回[a,b] 其中ab是出现一次的两个数字
def FindNumsAppearOnce(self, array):
# write code here
hashMap = {}
for i in array:
if str(i) in hashMap:
hashMap[str(i)] += 1
else:
hashMap[str(i)] = 1
res = []
for k in hashMap.keys():
if hashMap[k] == 1:
res.append(k)
return res
41.和为s的连续正数序列
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
class Solution:
def FindContinuousSequence(self, tsum):
# write code here
if tsum < 3:
return []
small = 1
big = 2
middle = (tsum + 1) // 2
curSum = small + big
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
42.和为s的两个数
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:
sum = array[start]+array[end]
if sum < tsum:
start +=1
elif sum > tsum:
end -= 1
else:
return [array[start],array[end]]
return []
43.左旋转字符串
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
class Solution:
def LeftRotateString(self, s, n):
# write code here
if s == None or len(s) <= 0:
return ''
strlist = list(s)
self.Reverse(strlist)
point = len(s)-n
frontList = self.Reverse(strlist[:point])
lastList = self.Reverse(strlist[point:])
resstr = ''.join(frontList) + ''.join(lastList)
return resstr
def Reverse(self,alist):
if alist == None or len(alist) <= 0:
return ''
StartIndex = 0
EndIndex = len(alist)-1
while StartIndex < EndIndex:
alist[StartIndex],alist[EndIndex] = alist[EndIndex],alist[StartIndex]
StartIndex += 1
EndIndex -= 1
return alist
取字符串分片在拼接就能搞定!
44.反转单词顺序
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
class Solution:
def ReverseSentence(self, s):
# write code here
l = s.split(' ')
return ' '.join(l[::-1])
45.扑克牌顺子
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。
class Solution:
def IsContinuous(self, numbers):
# write code here
if numbers == None or len(numbers)<=0:
return False
transdict={'A':1,'J':11,'Q':12,'K':13}
for i in range(len(numbers)):
if numbers[i] in transdict.keys():
numbers[i]=transdict[numbers[i]]
numbers = sorted(numbers)
numzero = 0
numgap = 0
i = 0
while i < len(numbers) and numbers[i] == 0:
numzero += 1
i += 1
small = numzero
big = small + 1
while big < len(numbers):
if numbers[big] == numbers[small]:
return False
numgap += numbers[big] - numbers[small] -1
big += 1
small += 1
return False if numgap > numzero else True
46.圆圈中最后剩下的数
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)`
class Solution:
def LastRemaining_Solution(self, n, m):
# write code here
if n < 1 or m < 1:
return -1
remainIndex = 0
for i in range(1, n+1):
remainIndex = (remainIndex + m) % i
return remainIndex
47.求1+2+3+…+n
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
class Solution:
def Sum_Solution(self, n):
# write code here
if n == 1:
return 1
return n + self.Sum_Solution(n-1)
48.不用加减乘除做加法
class Solution:
def Add(self, num1, num2):
# write code here
while num2 != 0:
temp = num1 ^ num2
num2 = (num1 & num2) << 1
num1 = temp & 0xFFFFFFFF#负数做处理
return num1 if num1 >> 31 == 0 else num1 - 4294967296 #考虑越界情况
49.把字符串转换成整数
将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
class Solution:
def StrToInt(self, s):
# write code here
import re #引入正则化模块
#正则化中^代表用^后面的开头,[-+]?表示[-+]可以出现,也可以不出现,\d匹配所有数字,\d+数字后面可以连接无数数字,但不能是其他东西,包括空格和字母
list_s = re.findall(r"^[-+]?\d+", str.strip()) #删除前,后空格。这样容易导致开始碰到字母就为空列表
#print(list_s)
if not list_s:
return 0 #字母开始列表是空的,直接返回0
else:
num =int(''.join(list_s)) #列表转化为字符串,然后转化为整数
if num >2**31 -1:
return 2**31 -1
elif num < -2**31:
return -2**31
else:
return num
50.表示数值的字符串
import re
class Solution:
# s字符串
def isNumeric(self, s):
# write code here
return re.match(r"^[\+\-]?[0-9]*(\.[0-9]*)?([eE][\+\-]?[0-9]+)?$",s)
51.字符流中第一个不重复的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
class Solution:
# 返回对应char
def __init__(self):
self.adict = {}
self.alist = []
def FirstAppearingOnce(self):
while len(self.alist) > 0 and self.adict[self.alist[0]] == 2:
self.alist.pop(0)
if len(self.alist) == 0:
return '#'
else:
return self.alist[0]
def Insert(self, char):
if char not in self.adict.keys():
self.adict[char] = 1
self.alist.append(char)
elif self.adict[char]:
self.adict[char] = 2
52.删除链表中重复的节点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
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
53.二叉树的下一个节点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
class Solution:
def GetNext(self, pNode):
# write code here
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
54.对称的二叉树
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
class Solution:
def isSymmetrical(self, pRoot):
# write code here
return self.selfIsSymmetrical(pRoot, pRoot)
def selfIsSymmetrical(self, pRoot1, pRoot2):
if pRoot1 == None and pRoot2 == None:
return True
if pRoot1 == None or pRoot2 == None:
return False
if pRoot1.val != pRoot2.val:
return False
return self.selfIsSymmetrical(pRoot1.left, pRoot2.right) and self.selfIsSymmetrical(pRoot1.right, pRoot2.left)
55.按之字行顺序打印二叉树
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
class Solution:
def Print(self, pRoot):
# write code here
if not pRoot:
return []
result, nodes = [], [pRoot]
right = True
while nodes:
curStack, nextStack = [], []
if right:
for node in nodes:
curStack.append(node.val)
if node.left:
nextStack.append(node.left)
if node.right:
nextStack.append(node.right)
else:
for node in nodes:
curStack.append(node.val)
if node.right:
nextStack.append(node.right)
if node.left:
nextStack.append(node.left)
nextStack.reverse()
right = not right
result.append(curStack)
nodes = nextStack
return result
56.把二叉树打印成多行
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
class Solution:
# 返回二维列表[[1,2],[4,5]]
def Print(self, pRoot):
# write code here
if pRoot == None:
return []
nodes = [pRoot]
res = []
while nodes:
curStack, nextStack = [], []
for node in nodes:
curStack.append(node.val)
if node.left:
nextStack.append(node.left)
if node.right:
nextStack.append(node.right)
res.append(curStack)
nodes = nextStack
return res
57.序列化二叉树
请实现两个函数,分别用来序列化和反序列化二叉树
class Solution:
def Serialize(self, root):
serializeStr = ''
if root == None:
return '#'
stack = []
while root or stack:
while root:
serializeStr += str(root.val) + ','
stack.append(root)
root = root.left
serializeStr += '#,'
root = stack.pop()
root = root.right
serializeStr = serializeStr[:-1]
return serializeStr
# write code here
def Deserialize(self, s):
# write code here
serialize = s.split(',')
Tree,sp = self.deserialize(serialize,0)
return Tree
def deserialize(self,s,sp):
if sp >= len(s) or s[sp] == '#':
return None,sp + 1
node = TreeNode(int(s[sp]))
sp += 1
node.left,sp = self.deserialize(s,sp)
node.right,sp = self.deserialize(s,sp)
return node, sp
58.二叉搜索数的第k个节点
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
class Solution:
# 返回对应节点TreeNode
def KthNode(self, pRoot, k):
# write code here
if k<=0 or not pRoot:
return None
treeStack = []
nodesQue = []
pNode = pRoot
while pNode or len(treeStack):
while pNode:
treeStack.append(pNode)
pNode = pNode.left
if len(treeStack):
pNode = treeStack.pop()
nodesQue.append(pNode)
pNode = pNode.right
if k > len(nodesQue):
return None
return nodesQue[k-1]
59.数据流中的中位数
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
class Solution:
def __init__(self):
self.arr=[]
def Insert(self, num):
self.arr.append(num)
self.arr.sort()
def GetMedian(self,fuck):
length=len(self.arr)
if length%2==1:
return self.arr[length//2]
return(self.arr[length//2]+self.arr[length//2-1])/2.0
60.滑动窗口的最大值
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
class Solution:
def maxInWindows(self, num, size):
# write code here
if not num or size <= 0:
return []
deque = []
if len(num) >= size:
index = []
for i in range(size):
while len(index) > 0 and num[i] > num[index[-1]]:
index.pop()
index.append(i)
for i in range(size, len(num)):
deque.append(num[index[0]])
while len(index) > 0 and num[i] >= num[index[-1]]:
index.pop()
if len(index) > 0 and index[0] <= i - size:
index.pop(0)
index.append(i)
deque.append(num[index[0]])
return deque
61.机器人的运动范围
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
class Solution:
def movingCount(self, threshold, rows, cols):
# write code here
memories = set()
def dfs(i,j):
def judge(i,j):
return sum(map(int, list(str(i)))) + sum(map(int, list(str(j)))) <= threshold
if not judge(i,j) or (i,j) in memories:
return
memories.add((i,j))
if i != rows - 1:
dfs(i + 1, j)
if j != cols - 1:
dfs(i, j + 1)
dfs(0,0)
return len(memories)