目录
二维数组中的查找
题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
# -*- 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]