●计算置信区间.
●服务器建立接收再多的连接,也只占用一个端口, 理解错误的人要回去补充下基础知识!
多项式 P(X)=a+bx+cx^2+dx^3 ,对于任意 x ,计算 P(X) 中最少需要用到乘法操作的次数是多少 答案3次 ??????????????????????
●进制的乘法:
k进制:
a*b=c 这种乘法都是用10进制来表示,本质是k进制.
例如3进制里面2*2=11
具体计算方法就是先当成10进制算,再转化成k进制即可.
2*2=4,4转化成3进制就是11.所以2*2=11
●如果某系统12*5=61成立,则系统采用的是()进制
下面计算这个题目:
假设是k进制,那么左边都转化成k进制后是 (k+2)*5=6*k+1 所以k=9
●先来先服务(FCFS, First Come First Serve)是最简单的调度算法,按先后顺序进行调度。
●
作业周转时间(Ti)=完成时间(Tei)-提交时间(Tsi)
作业平均周转时间(T)=周转时间/作业个数
作业带权周转时间(Wi)=周转时间/运行时间
响应比=(等待时间+运行时间)/运行时间
●
现有4个同时到达的作业J1,J2,J3和J4,它们的执行时间分别是1小时,3小时,5小时,7小时,系统按单道方式运行且采用短作业优先算法,则平均周转时间是()小时 计算:1+4+8+16 再/4 =7.5
●Linux文件权限一共10位长度,分成四段,第三段表示的内容是
文件所有者所在组的权限
进程所请求的一次打印输出结束后,将使进程状态从( )
等待态变为就绪态
电子邮件服务器之间相互传递邮件通常使用的协议是( )
SMTP
在网络协议中,定义控制信息格式的是( )
语法
3
在一个表中主键列的值是唯一的
一个类中的静态方法的调用可以:( )
通过类名调用
某软件公司欲开发一个图像处理系统,在项目初期开发人员对需求并不明确的情况下,采用( )方法比较合适
快速原型
如果两个人只能通过打电话接触,如何通过“打电话”实现“猜拳”?
找第三个人听
二、HAVING
HAVING语句通常与GROUP BY语句联合使用,用来过滤由GROUP BY语句返回的记录集。
HAVING语句的存在弥补了WHERE关键字不能与聚合函数联合使用的不足。
语法:
SELECT column1, column2, ... column_n, aggregate_function (expression)
FROM tables
WHERE predicates
GROUP BY column1, column2, ... column_n
HAVING condition1 ... condition_n; 所以有havign必须有group by 才能用.
SVM(支持向量机)与LR(逻辑回归)的数学本质上的区别是什么?
损失函数
ROC曲线的横、纵坐标分别表示?
FPR, TPR
You are given a data set. The data set has missing values which spread along 1 standard deviation from the median. What percentage of data would remain unaffected?
~32%
复习经典题目: 感觉这个思想 可以说是双移动指针.来控制数组下表
'''
[编程题] 排序次数
时间限制:1秒
空间限制:65536K
小摩有一个N个数的数组,他想将数组从小到大 排好序,但是萌萌的小摩只会下面这个操作:
任取数组中的一个数然后将它放置在数组的最后一个位置。
问最少操作多少次可以使得数组从小到大有序?
输入描述:
首先输入一个正整数N,接下来的一行输入N个整数。(N <= 50, 每个数的绝对值小于等于1000)
输出描述:
输出一行操作数
输入例子1:
4
19 7 8 25
输出例子1:
2
例子说明1:
19放到最后,25放到最后,两步完成从小到大排序
'''
while 1:
try :
tmp=int(input())
list1=[int(i)for i in input().split()]
a=sorted(list1)
i=0
j=0
count=0
while i<len(list1):
tmp1=list1[i]
tmp2=a[j]
if tmp1!=tmp2:
count+=1
i+=1
else:
i+=1
j+=1
print(count)
except:
break
'''
[编程题] 字符串问题
时间限制:1秒
空间限制:65536K
小摩手里有一个字符串A,小拜的手里有一个字符串B,B的长度大于等于A,所以小摩想把A串变得和B串一样长,这样小拜就愿意和小摩一起玩了。
而且A的长度增加到和B串一样长的时候,对应的每一位相等的越多,小拜就越喜欢。比如"abc"和"abd"对应相等的位数为2,为前两位。
小摩可以在A的开头或者结尾添加任意字符,使得长度和B一样。现在问小摩对A串添加完字符之后,不相等的位数最少有多少位?
输入描述:
第一行 为字符串A,第二行 为字符串B,
A的长度小于等于B的长度,B的长度小于等于100。
字符均为小写字母。
输出描述:
输出一行整数表示A串添加完字符之后,A B 不相等的位数最少有多少位?
输入例子1:
abe
cabc
输出例子1:
1
'''
a=input()
b=input()
res=len(b)-len(a)
count=float('inf')
for i in range(res+1):
tmp=b[i:len(a)+i]
out=0
for i in range(len(tmp)):
if tmp[i]!=a[i]:
out+=1
if out<count:
count=out
if len(a)==len(b):
tmp=b
out=0
for i in range(len(tmp)):
if tmp[i]!=a[i]:
out+=1
if out<count:
count=out
print(count)
数据库技术的根本目标是要解决数据共享的问题
尽管每个进程都有自己的内存地址,不同的进程可以同时将同一个内存页面映射到自己的地址空间中,从而达到共享内存的目的
经典题目还是不熟练
'''
53. 最大子序和
题目描述提示帮助提交记录社区讨论阅读解答
随机一题
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
'''
class Solution:
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
sum=nums[0]
maxi=-float('inf')
if sum>maxi:
maxi=sum
for i in range(1,len(nums)):
if sum<0:
sum=nums[i]
else:
sum=sum+nums[i]
if sum>maxi:
maxi=sum
return maxi
很难的走棋问题:思路是逆过来,考虑最后一步你进入时候需要多少粮食,从而可以逆着走到开始
[编程题] 走格子游戏
时间限制:1秒
空间限制:10485760K
G社正在开发一个新的战棋类游戏,在这个游戏中,角色只能向2个方向移动:右、下。移动需要消耗行动力,游戏地图上划分M*N个格子,当角色移动到某个格子上时,行动力就会加上格子上的值K(-100~100),当行动力<=0时游戏失败,请问要从地图左上角移动到地图右下角至少需要多少起始行动力,注意(玩家初始化到起始的左上角格子时也需要消耗行动力)
输入描述:
第一行输入格子行列数(格式为 M N),第2~M+1行每行输入N个数,作为格子值K,中间以空格分割;0 < M, N < 1000,-100 < K < 100
输出描述:
初始最小行动力
输入例子1:
2 3
-2 -3 3
-5 -10 1
输出例子1:
6
a=[int(i) for i in input().split()]
ppp=a
matrix=[]
for i in range(a[0]):
tmp=[int(j) for j in input().split()]
matrix.append(tmp)
memo={}
def main(a,b):#返回v,表示进入这个点a,b时候必须带多少食物
if (a,b) in memo:
return memo[a,b]
if a==ppp[0]-1 and b==ppp[1]-1:
memo[a,b]= max(1,1-matrix[a][b])
return memo[a,b]
if a!=ppp[0]-1 and b!=ppp[1]-1:
case1=main(a+1,b)-matrix[a][b]
case1=max(1,case1)
case2=main(a,b+1)-matrix[a][b]
case2=max(1,case2)
memo[a,b]= min(case1,case2)
return memo[a,b]
if b==ppp[1]-1:
case1=main(a+1,b)-matrix[a][b]
case1=max(1,case1)
memo[a,b]= case1
return memo[a,b]
if a==ppp[0]-1 :
case1=main(a,b+1)-matrix[a][b]
case1=max(1,case1)
memo[a,b]= case1
return memo[a,b]
print(main(0,0))
[编程题] 被3整除
时间限制:1秒
空间限制:32768K
小Q得到一个神奇的数列: 1, 12, 123,...12345678910,1234567891011...。
并且小Q对于能否被3整除这个性质很感兴趣。
小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。
输入描述:
输入包括两个整数l和r(1 <= l <= r <= 1e9), 表示要求解的区间两端。
输出描述:
输出一个整数, 表示区间内能被3整除的数字个数。
输入例子1:
2 5
输出例子1:
3
例子说明1:
12, 123, 1234, 12345...
其中12, 123, 12345能被3整除。
'''
菲薄拿起数列到底有多少个是3的倍数
'''
#经过试验,容易看出规律是 是,是,否,循环.
#a=[int(i) for i in input().split()]
a=[int(i) for i in input().split()]
tmp=a[0]
num1=a[0]//3*2
res=a[0]-a[0]//3*3
if res==1:
res=0
if res==2:
res=1
if res==3:
res=2
num1+=res
tmp=a[1]
num2=a[1]//3*2
res=a[1]-a[1]//3*3
if res==1:
res=0
if res==2:
res=1
if res==3:
res=2
num2+=res
if a[0]%3==0 or a[0]%3==2:
out=num2-num1+1
else:
out=num2-num1
print(out)
背包神马的最爱,果断递归加转tuple 字典记忆法即可.
[编程题] 牛牛的背包问题
时间限制:1秒
空间限制:32768K
牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。
牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。
牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。
输入描述:
输入包括两行
第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量。
第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积。
输出描述:
输出一个正整数, 表示牛牛一共有多少种零食放法。
输入例子1:
3 10
1 2 4
输出例子1:
8
例子说明1:
三种零食总体积小于10,于是每种零食有放入和不放入两种情况,一共有2*2*2 = 8种情况。
a=[int(i) for i in input().split()]
b=[int(i) for i in input().split()]
#a=[1,1]
#b=[2]
memo={}
def main(left,a):
if (left,tuple(a)) in memo:
return memo[(left,tuple(a))]
if a==[]:
return 1
case1=main(left,a[1:])
case2=0
if a[0]<=left:
case2=main(left-a[0],a[1:])
memo[(left,tuple(a))]= case1+case2
return memo[(left,tuple(a))]
print(main(a[1],b))
[编程题] 迷路的牛牛
时间限制:1秒
空间限制:32768K
牛牛去犇犇老师家补课,出门的时候面向北方,但是现在他迷路了。虽然他手里有一张地图,但是他需要知道自己面向哪个方向,请你帮帮他。
输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含一个正整数,表示转方向的次数N(N<=1000)。
接下来的一行包含一个长度为N的字符串,由L和R组成,L表示向左转,R表示向右转。
输出描述:
输出牛牛最后面向的方向,N表示北,S表示南,E表示东,W表示西。
输入例子1:
3
LRR
输出例子1:
E
a=int(input())
b=input()
#a=3
#b='LRR'
count=0
for i in b:
if i=='L':
count-=1
else:
count+=1
out=['W','N','E','S']
print(out[(1+count)%4])
请用文字描述 Hadoop 的 MapReduce 计算模型,可以从任务的提交、运行、交互、结束等阶段详细描述。根据你所描述的过程模型,是否有可以优化的空间?如果有,可以罗列一些 hadoop 已经实现的优化点,同时提出你自己的优化方案。
高次幂的2进制求解法:
372. 超级次方
题目描述提示帮助提交记录社区讨论阅读解答
随机一题
你的任务是计算 ab 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出。
示例 1:
a = 2
b = [3]
结果: 8
示例 2:
a = 2
b = [1,0]
结果: 1024
致谢:
特别感谢 @Stomach_ache 添加这道题并创建所有测试用例。
class Solution:
def superPow(self, a, b):
"""
:type a: int
:type b: List[int]
:rtype: int
"""
a1=''
for i in range(len(b)):
a1+=str(b[i])
a1=int(a1)
b=a1
b=bin(b)[2:]
c=[0]*len(b)
tmp=a
for i in range(0,len(b)):
if i==0:
c[-1]=a%1337
else:
tmp=tmp**2%1337
c[-i-1]=tmp
out=1
for i in range(len(b)):
if b[i]=='1':
out*=c[i]
out%=1337
return out
今日头条很精彩的题目: 自己没做出来,看了别人的方法. 学习了.如果取值范围很小,可以考虑遍历取值范围来找!!
[编程题] 编程题2
时间限制:3秒
空间限制:131072K
给定一个数组序列, 需要求选出一个区间, 使得该区间是所有区间中经过如下计算的值最大的一个:
区间中的最小数 * 区间所有数的和最后程序输出经过计算后的最大值即可,不需要输出具体的区间。如给定序列 [6 2 1]则根据上述公式, 可得到所有可以选定各个区间的计算值:
[6] = 6 * 6 = 36;
[2] = 2 * 2 = 4;
[1] = 1 * 1 = 1;
[6,2] = 2 * 8 = 16;
[2,1] = 1 * 3 = 3;
[6, 2, 1] = 1 * 9 = 9;
从上述计算可见选定区间 [6] ,计算值为 36, 则程序输出为 36。
区间内的所有数字都在[0, 100]的范围内;
输入描述:
第一行输入数组序列长度n,第二行输入数组序列。
对于 50%的数据, 1 <= n <= 10000;
对于 100%的数据, 1 <= n <= 500000;
输出描述:
输出数组经过计算后的最大值。
输入例子1:
3
6 2 1
输出例子1:
36
#最小值为tmp那么,能扩多大
n=int(input())
list1=[int(i) for i in input().split()]
out=0
for tmp in range(101):
sum=0
list1.append(0)#为了最后停下来
for i in range(len(list1)):
if list1[i]>=tmp:
sum+=list1[i]
else:
out=max(sum*tmp,out)
sum=0
print(out)
奶牛题:
[编程题] 奶牛编号
时间限制:1秒
空间限制:32768K
牛牛养了n只奶牛,牛牛想给每只奶牛编号,这样就可以轻而易举地分辨它们了。 每个奶牛对于数字都有自己的喜好,第i只奶牛想要一个1和x[i]之间的整数(其中包含1和x[i])。
牛牛需要满足所有奶牛的喜好,请帮助牛牛计算牛牛有多少种给奶牛编号的方法,输出符合要求的编号方法总数。
输入描述:
输入包括两行,第一行一个整数n(1 ≤ n ≤ 50),表示奶牛的数量 第二行为n个整数x[i](1 ≤ x[i] ≤ 1000)
输出描述:
输出一个整数,表示牛牛在满足所有奶牛的喜好上编号的方法数。因为答案可能很大,输出方法数对1,000,000,007的模。
输入例子1:
4
4 4 4 4
输出例子1:
24
a=int(input())
b=[int(i) for i in input().split()]
b.sort()
out=1
for i in range(len(b)):
out*=b[i]-i
print(out%int(1e9+7))
又没做出来,还是基本技能不熟练,看的别人的启发. 关键是重要技能 如何求解两个子串的最长公共子序列不熟练.
[编程题] 平方串
时间限制:1秒
空间限制:32768K
如果一个字符串S是由两个字符串T连接而成,即S = T + T, 我们就称S叫做平方串,例如"","aabaab","xxxx"都是平方串.
牛牛现在有一个字符串s,请你帮助牛牛从s中移除尽量少的字符,让剩下的字符串是一个平方串。换句话说,就是找出s的最长子序列并且这个子序列构成一个平方串。
输入描述:
输入一个字符串s,字符串长度length(1 ≤ length ≤ 50),字符串只包括小写字符。
输出描述:
输出一个正整数,即满足要求的平方串的长度。
输入例子1:
frankfurt
输出例子1:
4
a=input()
memo={}
def main(s1,s2,a,b):#返回严格以index a结尾的s1的子串和严格以index b结尾的s2的子串
if (s1,s2,a,b) in memo:
return memo[(s1,s2,a,b)]
if a==0:
if s1[0] in s2[:b+1]:
return 1
else:
return 0
if b==0:
if s2[0] in s1[:a+1]:
return 1
else:
return 0
if s1[a]==s2[b]:
case1=main(s1,s2,a-1,b-1)+1
else:
case1=0
case2=main(s1,s2,a-1,b)
case3=main(s1,s2,a,b-1)
memo[(s1,s2,a,b)]=max(case1,case2,case3)
return memo[(s1,s2,a,b)]
out=0
for i in range(len(a)-1):
first=a[:i+1]
second=a[i+1:]
out=max(out,main(first,second,len(first)-1,len(second)-1))
print(out*2)
两个子串的最长公共子序列不熟练. 这个代码要多联系.当成常用的模块来写 效率N^2
'''
最长公共子序列
'''
def main(s1,s2,a,b):#返回严格以index a结尾的s1的子串和严格以index b结尾的s2的子串
#的最长公共子序列的长度.
if a==0:
if s1[0] in s2[:b+1]:
return 1
else:
return 0
if b==0:
if s2[0] in s1[:a+1]:
return 1
else:
return 0
if s1[a]==s2[b]:
case1=main(s1,s2,a-1,b-1)+1
else:
case1=0
case2=main(s1,s2,a-1,b)
case3=main(s1,s2,a,b-1)
return max(case1,case2,case3)
a='frank'
b='furt'
print(main(a,b,len(a)-1,len(b)-1))
两个子串的最长公共子串. 效率N^2 注意把握这2个代码的区别,只是初始化时有区别:1.子序列的用in 2.子串的用==第二个数组最后一个判断!
'''
最长公共子串
'''
a=input()
b=input()
def main(s1,s2,a,b):#返回严格以index a结尾的s1的子串和严格以index b结尾的s2的子串
#的最长公共子序列的长度.
if a==0:
if s1[0] ==s2[b]:
return 1
else:
return 0
if b==0:
if s2[0] in s1[a]:
return 1
else:
return 0
if s1[a]==s2[b]:
case1=main(s1,s2,a-1,b-1)+1
else:
case1=0
case2=main(s1,s2,a-1,b)
case3=main(s1,s2,a,b-1)
return max(case1,case2,case3)
print(main(a,b,len(a)-1,len(b)-1))
补括号
[编程题] 缺失的括号
时间限制:1秒
空间限制:65536K
一个完整的括号字符串定义规则如下:
1、空字符串是完整的。
2、如果s是完整的字符串,那么(s)也是完整的。
3、如果s和t是完整的字符串,将它们连接起来形成的st也是完整的。
例如,"(()())", ""和"(())()"是完整的括号字符串,"())(", "()(" 和 ")"是不完整的括号字符串。
牛牛有一个括号字符串s,现在需要在其中任意位置尽量少地添加括号,将其转化为一个完整的括号字符串。请问牛牛至少需要添加多少个括号。
输入描述:
输入包括一行,一个括号序列s,序列长度length(1 ≤ length ≤ 50).
s中每个字符都是左括号或者右括号,即'('或者')'.
输出描述:
输出一个整数,表示最少需要添加的括号数
输入例子1:
(()(()
输出例子1:
2
data=input()
tmp=[]
for i in range(len(data)):
if data[i]=='(':
tmp.append(1)
else:
tmp.append(-1)
k=0
out=0
import copy
old=tmp
old=copy.deepcopy(tmp)
for i in range(len(old)):
while k<len(tmp)-1:
if tmp[k]==1 and tmp[k+1]==-1:
tmp.pop(k)
tmp.pop(k)
out+=1
else:
k+=1
k=0
print(len(old)-out*2)
restful
https://baijiahao.baidu.com/s?id=1605768542638539831&wfr=spider&for=pc
[编程题] 括号匹配
时间限制:1秒
空间限制:32768K
一般的括号匹配问题是这样的:
给出一个字符串,判断这个括号匹配是不是合法的括号匹配。
如"((" 和 "())"都不是合法的括号匹配,但是"()()()","(()())()"等就是合法的括号匹配。
这个问题解决起来非常简单,相信大家都知道怎么解决。
现在给出一个加强版的括号匹配问题: 给出n个由括号 '(' 和 ‘)’ 组成的字符串,请计算出这些字符串中有多少对字符串满足si + sj是合法的括号匹配。如果si + sj和sj + si都是合法的括号匹配(i ≠ j),那么这两种搭配都需要计入答案;如果对于si,si + si是合法的括号匹配,那么也需要计入答案。
输入描述:
第一行是一个整数n,表示字符串的个数;
接下来n行是n个非空字符串,全部由'('和')'组成。
1 <= n <= 3 * 105,字符串的长度之和不超过3 * 105。
输出描述:
一个整数,表示满足条件的字符串对的数量。
输入例子1:
3
()
(
)
输出例子1:
2
输入例子2:
5
(()
)))))
()()()
(((
))
输出例子2:
1
验证bst:
非常牛逼代码:
class Solution(object):
def ValidBST(self,root,min,max):
if (root is None):
return True
elif (root.val <= min or root.val >= max):
return False
else:
return (self.ValidBST(root.left,min,root.val) and self.ValidBST(root.right,root.val,max))
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
return self.ValidBST(root,-2**62,2**62)
【单选】在卷积神经网络计算中,已知输入特征层大小为32x32x64, 使用标准卷积计算,带偏置项,卷积核大小为3*3,输出特征层数目为64,
请问卷积层的参数个数为?
特征是64 输出64 中间是9 kernal 乘起来是64*64*9
偏执项是64 所以加起来36928 ,偏执项跟核大小,特征多少无关,他们都共用.只跟输出特征有关.
正确答案: D 你的答案: 空 (错误)
AdaGrad
SGD
L-BFGS
Subgradient method
次梯度下降法:就是用单侧极限来代替极限,从而对不可导函数也能求导.
正确答案: B 你的答案: 空 (错误)
动态规划
蒙特卡洛
Q- learning
Sarsa
算法竞赛书的题目:
'''
算法竞赛入门经典(第二版)
表达式树:
class node():
def __init__(self,a):
self.left=None
self.right=None
self.val=a
print(node(3))
def build_tree(s):
if s[0]=='(' and s[-1]==')':
s=s[1:-1]
if len(s)==1:
a=node(s)
return a
if ')'in s:
end=s.rindex(')')
first=s.index('(')
jiajian=[]
chengchu=[]
#下面情况就没有括号了
for i in range(len(s)):
if i in range(first,end):
continue
if s[i]=='+' or s[i]=='-':
jiajian.append(i)
if s[i]=='*' or s[i]=='/':
chengchu.append(i)
if jiajian==[]:
final=chengchu[-1]
else:
final=jiajian[-1]
else:
#无括号情况.
#比如s=a+b*c+d-e
jiajian=[]
chengchu=[]
#下面情况就没有括号了
for i in range(len(s)):
if s[i]=='+' or s[i]=='-':
jiajian.append(i)
if s[i]=='*' or s[i]=='/':
chengchu.append(i)
if jiajian==[]:
final=chengchu[-1]
else:
final=jiajian[-1]
#final就是最后需要的分割点
print(final)
print('#############')
a=node(s[final])
a.left=build_tree(s[:final])
a.right=build_tree(s[final+1:])
return a
s='a+b*(c-d)-c/f'
#效果还不错
print(build_tree(s).val)
'''
一个双函数递归,加记忆体的题目
'''
程序员面试代码指南
排成一条直线的纸牌博弈问题.
arr=[1,2,100,4] 返回101
arr=[1,100,2] 返回100
定义f(i,j)表示arr[i,j]这个拍如果先拿会得的分数
定义s(i,j)表示arr[i,j]这个拍如果后拿会得的分数
下面的区间表示包含端点.
如果i==j,那么f(i,j)=arr[i] s(i,j)=0.
如果j>i,那么就有f(i,j)=max(s[i+1,j]+arr[i],arr[j]+s[i,j-1])
s(i,j)=min(f[i+1,j],f[i,j-1])
#因为s是当前步的后拿的那一个人,因为对方是聪明绝顶的,所以我只能去到min!!!!!
#这步很重要,我一开始取得max就错了.
'''
def f(i,j):
if i==j:
return arr[i]
else:
return max(s(i+1,j)+arr[i],arr[j]+s(i,j-1))
def s(i,j):
if i==j:
return 0
else:
return min(f(i+1,j),f(i,j-1))
arr=[1,2,100,4]
print(max(f(0,len(arr)-1),s(0,len(arr)-1)))
print(s(0,len(arr)-1))
上个题目改成记忆体:
def f(i,j):
if (i,j)in memo1:
return memo1[(i,j)]
if i==j:
return arr[i]
else:
memo1[(i,j)]=max(s(i+1,j)+arr[i],arr[j]+s(i,j-1))
return memo1[(i,j)]
def s(i,j):
if (i,j)in memo2:
return memo2[(i,j)]
if i==j:
return 0
else:
memo2[(i,j)]=min(f(i+1,j),f(i,j-1))
return memo2[(i,j)]
arr=[1,2,1000,40]*250
memo1={}
memo2={}
print(max(f(0,len(arr)-1),s(0,len(arr)-1)))
程序员代码面试指南的部分题目:
# -*- coding: utf-8 -*-
"""
Spyder Editor
This is a temporary script file.
"""
# -*- coding: utf-8 -*-
"""
Created on Fri Jul 20 10:58:02 2018
#如果跑不了就是编码问题,用记事本另存一下,把编码改成utf-8保存即可.
#3d图片利用cmd跑这种画图程序,就能旋转图片了.spyder不能旋转
@author: 张博
"""
'''
读取csv最稳的方法:
import pandas as pd
f = open('/Users/michael/gbk.csv', 'r', encoding='gbk', errors='ignore')
data = pd.read_csv(f,header=None)
'''
'''
画图模板:
from matplotlib import pyplot
data=[]
pyplot.plot(data,color='black')
pyplot.show()
'''
'''
获取当前时间:
import datetime
nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')#现在
nowTime=((nowTime)[:-3])
print(nowTime)
'''
'''
写文件的模板
with open(r'c:/234/wucha.txt','w') as f:
wucha=str(wucha)
f.write(wucha)
'''
'''
手动加断电的方法:raise
'''
'''
excel表格实用技巧:
全选然后选开始-行和列-最适合的列宽.
这样看表格清晰多了!
'''
'''
时间序列画图
from matplotlib import pyplot
#画布大小
pyplot.rcParams['figure.figsize'] = (300, 3) # 设置figure_size尺寸
import matplotlib.dates as mdates
ax=plt.gca()
pyplot.rcParams['image.cmap'] = 'gray' #
xfmt = mdates.DateFormatter('%y-%m-%d %H:%M')
ax.xaxis.set_major_formatter(xfmt)
#下面这个是时间序列的间隔时间
plt.xticks(pd.date_range(data[0][0],data[-1][0],freq='2H'),rotation=90)
#样式
pyplot.plot(data[:,0],data[:,1],color='red',linewidth = 0.7)
pyplot.show()
'''
'''
#画3d
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot
pyplot.rcParams['figure.figsize'] = (3, 3) # 设置figure_size尺寸
fig=plt.figure()
ax3d=Axes3D(fig) #绘制3D图形
ax3d.scatter(data[:,1],data[:,2],data[:,0],c='r',marker=".")
pyplot.show()
'''
'''
非数值编码
#编码
from sklearn.preprocessing import LabelEncoder
a=a.values #切换成ndarry
encoder = LabelEncoder()
for i in range(5):
a[:,i] = encoder.fit_transform(a[:,i])
'''
'''
#标准化
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
a = scaler.fit_transform(a)
print(a)
'''
'''
降维可视化:
from sklearn.manifold import TSNE
#data可以是多少维都可以,都能降成2维
tsne=TSNE()
tsne.fit_transform(data) #进行数据降维,降成两维
#a=tsne.fit_transform(data_zs) #a是一个array,a相当于下面的tsne_embedding_
tsne=pd.DataFrame(tsne.embedding_) #转换数据格式
print(tsne)
tsne['聚类类别']=label_pred
print(tsne)
d=tsne[tsne[u'聚类类别']==0]
plt.plot(d[0],d[1],'r.')
d=tsne[tsne[u'聚类类别']==1]
plt.plot(d[0],d[1],'go')
d=tsne[tsne[u'聚类类别']==2]
plt.plot(d[0],d[1],'b*')
d=tsne[tsne[u'聚类类别']==3]
plt.plot(d[0],d[1],'y+')
plt.show()
#map基本用法:另外一个就是reduce,把上一步的结果迭代到写一个.比较花哨.不写了
a=map(str,[1,2,3,4])
b=[print(type(i)) for i in a]
#从下面这个看出来如果列表生成式即List Comprehensions 里面的套用函数是一个无返回值的,那么就返回None
#b的触发效果就是打印这些type,这个写法很方便,比for循环方便多了.
print(b)
'''
'''
#sort基本用法
print(sorted([36, 5, -12, 9, -21], key=abs))
print(sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower))
print(sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True))
#lambda函数:
list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
'''
'''
#装饰器例子:给now函数加一个功能,调用之前打印这个函数的名字.
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def now():
print('2015-3-25')
now()
#偏函数:把一个函数传好参数之后定义为一个新的函数
def int2(x, base=2):
return int(x, base)
print(int2('1011010'))
'''
'''
给实例加一个方法和给类加一个方法:
class Student(object):
pass
s = Student()
def set_age(self, age): # 定义一个函数作为实例方法
self.age = age
from types import MethodType
s.set_age = MethodType(set_age, s) # 给实例绑定一个方法
s.set_age(25) # 调用实例方法
print(s.age)
#下面是给类加一个方法,直接=赋值即可,一上这两种动态加入方法的方法教动态方法.
def set_score(self, score):
self.score = score
Student.set_score = set_score
s.set_score(100)
print(s.score)
#限制实例加入的方法:slot函数,只能加入name和age两个函数
bb
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
def set_score(self, score):
self.score = score
Student.set_score = set_score
s=Student()
s.set_score(3)
print(s.score)
'''
'''
property函数:
class Student(object):
@property #利用property和 .setter,函数来实现对函数变量的检查.
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
a=Student()
a.score=324.4
print(a.score)
'''
'''
#json和字典互转
import json
d = dict(name='Bob', age=20, score=88)
print(json.dumps(d))
json_str=json.dumps(d)
print(json.loads(json_str))
print(type(json.loads(json_str)))
'''
'''
总结一下就是,多任务的实现有3种方式:
多进程模式;
多线程模式;
多进程+多线程模式。
多进程
#奇怪用cmd就能跑这个程序,spyder就不行
from multiprocessing import Pool
import os, time, random
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Pool(4) #多个进程的书写用pool管理更方便,不然需要很多的join很烦
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close() #必须在join前面写上关闭pool
p.join() #表示Pool里面的子进程都跑完了,才开始运行下面的代码.
print('All subprocesses done.')
#用queue来做两个进程之间的通信.
from multiprocessing import Process, Queue
import os, time, random
def write(q):
print('Process to write: %s' % os.getpid())
for value in ['A', 'B', 'C']:
print('Put %s to queue...' % value)
q.put(value)
time.sleep(random.random())
# 读数据进程执行的代码:
def read(q):
print('Process to read: %s' % os.getpid())
while True:
value = q.get(True)
print('Get %s from queue.' % value)
if __name__=='__main__':
# 父进程创建Queue,并传给各个子进程:
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
# 启动子进程pw,写入:
pw.start()
# 启动子进程pr,读取:
pr.start()
# 等待pw结束:
pw.join()
# pr进程里是死循环,无法等待其结束,只能强行终止:
pr.terminate()
'''
'''
#线程之间共用类,用xxx=threading.local()创建.
import threading
# 创建全局ThreadLocal对象: 本质是线程都共享这个类,然后每个线程的对象是这个类的一个对象
#用字典实现的,对象=字典[线程号]
local_school = threading.local()
def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name))
print(threading.current_thread())
def process_thread(name):
# 绑定ThreadLocal的student:
local_school.student = name
process_student()
t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')
#比如t1这个线程:先进入process_thread函数,然后进入process_student函数.
#因为local_school是thread.local的资源,所以不同线程之间不共享.
t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
'''
'''
用异步IO编程模型来实现多任务是一个主要的趋势。
对应到Python语言,单线程的异步编程模型称为协程,有
了协程的支持,就可以基于事件驱动编写高效的多任务程序。我们会在后面讨论如何编写协程。
'''
'''
对于未知编码的bytes,要把它转换成str,需要先“猜测”编码。猜测的方式是先收集各种编码的
特征字符,根据特征字符判断,就能有很大概率“猜对”。
当然,我们肯定不能从头自己写这个检测编码的功能,这样做费时费力。chardet这个第三方库正好
就派上了用场。用它来检测编码,简单易用。
import chardet
data = '离离原上草,一岁一枯荣'.encode('utf-8')
print(chardet.detect(data))
'''
'''
#python 运维
物理内存(RAM)指的是RAM(即内存条)提供的临时数据存储空间
交换区指Unix/Linux系统前台与后台之间数据交换的场所,即为Unix/Linux系统的虚拟内存
虚拟内存泛指将临时数据存储于磁盘存储器上的技术(简单点说就是划出一部分磁盘作为临时的R
AM),Windows系统的“虚拟内存”,Linux系统的“交换区”都是虚拟内存
import psutil
print(psutil.cpu_count()) # CPU逻辑数量)
print(psutil.cpu_count(logical=False))# CPU物理核心
print(psutil.cpu_times())
#再实现类似top命令的CPU使用率,每秒刷新一次,累计10次:
for x in range(1):
print(psutil.cpu_percent(interval=1, percpu=True))
print(psutil.virtual_memory())
print(psutil.swap_memory())
print(psutil.disk_partitions())
print(psutil.disk_usage('/'))
print(psutil.disk_io_counters())
print(psutil.net_io_counters() )
print(psutil.net_if_addrs())
print(psutil.pids())
print(psutil.test())
'''
'''
网络通信:
网络通信是两台计算机上的两个进程之间的通信。
端口有什么作用?在两台计算机通信时,只发IP地址是不够的,因为同一台计算机上跑着多个网络
程序。一个TCP报文来了之后,到底是交给浏览器还是QQ,就需要端口号来区分。每个网络程序都向
操作系统申请唯一的端口号,这样,两个进程在两台计算机之间建立网络连接就需要各自的IP地址和
各自的端口号。
#TCP,UDP就是用socket!来实现的.
#TCP编程服务端:
import threading
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#SOCK_STREAM表示TCP
# 监听端口:
s.bind(('127.0.0.1', 9999)) #跟下面的客户端端口要一致.
s.listen(5)#传入的参数指定等待连接的最大数量:
print('Waiting for connection...')
#每个连接都必须创建新线程(或进程)来处理,否则,单线程在处理连接的过程中,无法接受其他客户端的连接:
def tcplink(sock, addr):
print('Accept new connection from %s:%s...' % addr)
sock.send(b'Welcome!')
while True:
data = sock.recv(1024)
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
sock.close()
print('Connection from %s:%s closed.' % addr)
while True:
# 接受一个新连接:
sock, addr = s.accept()
# 创建新线程来处理TCP连接:
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
#TCP配套客户端:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('127.0.0.1', 9999))
# 接收欢迎消息:
print(s.recv(1024).decode('utf-8'))
for data in [b'Michael', b'Tracy', b'Sarah']:
# 发送数据:
s.send(data)
print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
UDP的通信写法:使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,
就可以直接发数据包。但是,能不能到达就不知道了。
#UDP服务器的写法.
import threading
import socket
import time
#SOCK_DGRAM表示UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口:
s.bind(('127.0.0.1', 9999))
print('Bind UDP on 9999...')
while True:
# 接收数据:
data, addr = s.recvfrom(1024)
print('Received from %s:%s.' % addr)
s.sendto(b'Hello, %s!' % data, addr)
#UDP客户端
import threading
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', b'Tracy', b'Sarah']:
# 发送数据:
s.sendto(data, ('127.0.0.1', 9999))
# 接收数据:
print(s.recv(1024).decode('utf-8'))
s.close()
'''
'''
数据库
一行记录可以对应一个表.就叫关联性数据库.
import sqlite3
# 如果文件不存在,会自动在当前目录创建:
conn = sqlite3.connect('test.db')
# 创建一个Cursor:
cursor = conn.cursor()
# 执行一条SQL语句,创建user表:
cursor.execute('create table user (id varchar(20) primary key, name varchar(20))')
# 继续执行一条SQL语句,插入一条记录:
cursor.execute('insert into user (id, name) values (\'1\', \'Michael\')')
# 通过rowcount获得插入的行数:
print(cursor.rowcount)
# 关闭Cursor:
cursor.close()
# 提交事务:
conn.commit()
# 关闭Connection:
conn.close()
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
cursor.execute('select * from user where id=?', ('1',))
values = cursor.fetchall()
print(values)
'''
'''
#mysql安装:pip install mysql-connector
import mysql.connector
#默认是没有密码的
conn = mysql.connector.connect(user='root', password='', database='test')
cursor = conn.cursor()
#简历一个叫user的表
cursor.execute('create table user (id varchar(20) primary key, name varchar(20))')
cursor.execute('insert into user (id, name) values (%s, %s)', ['1', 'Michael'])
print(cursor.rowcount)
conn.commit() #提交操作
cursor.close()
cursor = conn.cursor()
cursor.execute('select * from user where id = %s', ('1',))
values = cursor.fetchall()
print(values)
cursor.close()
conn.close()
'''
'''
在Python中,最有名的ORM框架是SQLAlchemy。我们来看看SQLAlchemy的用法。
作用就是读取数据的每一行为一个object对象.
# 导入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# 创建对象的基类:
Base = declarative_base()
# 定义User对象:
class User(Base):
# 表的名字:
__tablename__ = 'user'
# 表的结构:
id = Column(String(20), primary_key=True)
name = Column(String(20))
# 初始化数据库连接:
engine = create_engine('mysql+mysqlconnector://root:@localhost:3306/test')
# 创建DBSession类型:
DBSession = sessionmaker(bind=engine)
#添加操作
# 创建session对象:
session = DBSession()
# 创建新User对象:
new_user = User(id='5', name='Bob')
# 添加到session:
session.add(new_user)
# 提交即保存到数据库:
session.commit()
# 关闭session:
session.close()
#查询操作
# 创建Session:
session = DBSession()
# 创建Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:
user = session.query(User).filter(User.id=='5').one()
# 打印类型和对象的name属性:
print('type:', type(user))
print('name:', user.name)
# 关闭Session:
session.close()
'''
'''
异步
看起来A、B的执行有点像多线程,但协程的特点在于是一个线程执行,那和多线程比,协程有何优势?
最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有
线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享
资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
#异步io框架,两个任务同时打印同时等待
import threading
import asyncio
@asyncio.coroutine
def hello():
print('Hello world! (%s)' % threading.currentThread())
yield from asyncio.sleep(1)
print('Hello again! (%s)' % threading.currentThread())
loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
'''
'''
常用的树结构:
class node():
def __init__(self,val):
self.val=val
self.left=None
self.right=None
#一个比较奇怪的是:a=b.right 那么修改a的时候不会修改b.right的.
#修改b.right只能修改b.right=c 即修改树的值只能从父节点修改,修改
#节点自身没用.原因就是python的=赋值修改是按照值来存储的,不是地址
'''
'''
程序员面试代码指南
排成一条直线的纸牌博弈问题.
arr=[1,2,100,4] 返回101
arr=[1,100,2] 返回100
定义f(i,j)表示arr[i,j]这个拍如果先拿会得的分数
定义s(i,j)表示arr[i,j]这个拍如果后拿会得的分数
下面的区间表示包含端点.
如果i==j,那么f(i,j)=arr[i] s(i,j)=0.
如果j>i,那么就有f(i,j)=max(s[i+1,j]+arr[i],arr[j]+s[i,j-1])
s(i,j)=min(f[i+1,j],f[i,j-1])
#因为s是当前步的后拿的那一个人,因为对方是聪明绝顶的,所以我只能去到min!!!!!
#这步很重要,我一开始取得max就错了.
'''
#跳跃游戏
arr=[3,2,3,1,1,4]
count=0
def main(arr):
global count
first=arr[0]
if first>=len(arr)-1:
count+=1
return
tmp=arr[1:first+1]
for i in range(len(tmp)):
tmp[i]+=i
m=max(tmp)
tmp=tmp[::-1]
m=tmp.index(m)
m=len(tmp)-m
arr=arr[m:]
count+=1
print(arr)
return main(arr)
main(arr)
print(count)
#n皇后问题
#程序员面试指南P239
#递归方法来解最简单,不用回溯法.代码非常漂亮
def valid(record ,i,j):
#跟之前i-1行是否冲突
for k in range(i):
if j==record[k] or abs(record[k]-j)==abs(i-k):
return False
return True
def process(i,record,n):
#函数表示第i行应该用多少来补,返回res
if i==n:
return 1
res=0
for j in range(n):
if valid(record,i,j):
record[i]=j
res+=process(i+1,record,n)#这步进行递归
return res
def num(n):
if (n<1):
return 0
record=[0]*n
return process(0,record,n)
print(num(10))
#字符串中数字子串的和
def main(s):
save=''
#扫描判定即可
for i in range(len(s)):
if i!=0:
if s[i-1] in '0123456789' and s[i]=='-':
save+='*'
save+='-'
if s[i] in '0123456789' or s[i] =='-':
save+=s[i]
elif s[i-1] in '0123456789' or s[i-1]=='-':
save+='*'
if i==0:
if s[i] in '0123456789' or s[i] =='-':
save+=s[i]
#最后用try来转化类型即可.
return save#减号前面如果是数字也加*
print(main('1-----A1CD2huujoE--33--9'))
#去掉字符串中连续出现的k个0的子串
def main(s,k):
#遍历一遍,把需要剔除的子串的尾dex放入数组中
out=[]
count=0
for i in range(len(s)):
if s[i]=='0':
count+=1
if count==k and i==len(s)-1:
out.append(i)
elif count==k and s[i+1]!='0':
out.append(i)
else:
count=0
return out
print(main('A000B00',2)) #看出已经找打了所有需要找到的index
#判断两个字符是否互相是旋转词
def main(s1,s2):
save={}
for i in range(len(s1)):
tmp=s1[i+1:]+s1[:i+1]
save[tmp]=1
return s2 in save
print(main('cdab','abcd'))
#替换字符串中连续出现的指定字符串
def main(s,from1,to):
s=s.replace(from1,to,1) #参数1表示只替换1次
s=s.replace(from1,'')
return s
print(main('123abcabc','abc','X'))
#字符串的统计字符串
def main(s):
s+='*' #填补一个最后的废字符,来保证边缘点的判断
out=[]
for i in range(len(s)):
if i==0:
tmp=s[0]
count=1
else:
if s[i]==s[i-1]:
count+=1
else:
out.append((tmp,count))
tmp=s[i]
count=1
return out
print(main('aaabbadddffc'))
#判断字符串中所有字符是否只出现一次
def main(s):
return len(set(s))==len(s)
print(main('abc'))
#翻转字符串
def main(s):
s=s.split()
s=s[::-1]
s=' '.join(s) #表示用空格来相连s这个数组
return s
print(main('dog loves pig'))
#数组中两个字符串的最小距离
def main(s,s1,s2):
if s1=='null' or s2=='null' or s1 not in s or s2 not in s:
return -1
else:
first=-float('inf')
second=-float('inf')
out=float('inf')
#从s的头开始扫描,每读一个s1的字符就跟s2的比较.
#每读到一个s2的字符集跟s1的位置first比较
for i in range(len(s)):
if s[i]==s1:
first=i
out=min(out,abs(first-second))
if s[i]==s2:
second=i
out=min(out,abs(first-second))
return out
print(main('1333200000031','1','2'))
#添加最少的字符使得字符串的整体都是回文字符串
'''
例子:'ABA' 返回'ABA' 因为不用添加
'AB' 返回'ABA' 因为这是最少的添加方案只添加两个一个字符.
注意可以往任意位置添加字符.
'''
def main(s):
if s==s[::-1]:
return s
else:
if len(s)==2:
return s+s[0]
else:
if s[0]==s[-1]:
case1=s[0]+main(s[1:-1])+s[-1]
case2='0'*999999 #为了下面取min时候不发生未定义变量的bug
case3='0'*999999
else:
case1=s[0]+s[-1]+main(s[1:-1])+s[-1]+s[0]
case2=s[0]+main(s[1:])+s[0]
case3=s[-1]+main(s[:-1])+s[-1]
m=min(len(case1),len(case2),len(case3))
if len(case1)==m:
return case1
elif len(case2)==m:
return case2
else:
return case3
'''
动态规划:
s[i,j]
'''
#妈的各种乱写居然好像可以.
print(main('acbcdax'))
#括号字符串的有效性和最长有效长度
#下面求解有效长度,动态规划,其实是一个挺难的题目
def final(s):
def main(s,j):#返回值表示s的子串里面必须以j_index结尾的子串里面最长的有效括号.
if j==0:
return 0
if j==1:
if s[0]=='(' and s[1]==')':
return 2
else:
return 0
if s[j]=='(':
return 0
else:
#上一个字符用了多长
last=main(s,j-1)
pre=j-last-1
if pre>=0 and s[pre]=='(':
if pre>0:
return last+2+main(s,pre-1)
else:
return last+2
out=[]
for j in range(len(s)):
out.append(main(s,j))
return max(out)
print (final('()(()()('))
#0的左边必须有1的二进制字符串的数量
'''
例子:N表示字符串的长度
N=1时,返回1
N=2时,返回2 10,11
N=3时,返回3 101,110,111
分析:
也就是0不能放第一个位置上.100不对,因为第二个0的紧贴的左边必须是1,不能是0
所以就是101010这种排列才可以.也就是10这个字符是捆绑的其他时候必须是1字符,
'''
def main(N):
if N==1:
return 1
if N==2:
return 2
# 打算用动态规划来做
#第一种情况表示开始位置用10来填充
case1=main(N-2)
#第二种情况表示开始位置用11来填充
case2=main(N-1)
return case1+case2
print(main(5)) #本体答案就是类似斐波那契数列
#拼接所有字符串产生的字典顺序最小的字符串
def main(l,dex):
#动态规划,返回利用到dex指标的子数组返回的最小的字符串.然后后面的往直前的字符串里面插即可.
if dex==0:
return [l[0]]
old=main(l,dex-1)
i=0
new=old[:i]+[l[dex]]+old[i:]
for i in range(1,dex+1):#所有插的可能性都插一遍即可.
new2=old[:i]+[l[dex]]+old[i:]
if ''.join(new2)<''.join(new):
new=new2
return new
def final(l):
return main(l,len(l)-1)
print(main(['b','ba'],1)) #虽然这个题目是4星的写起来还可以
print(final(['b','ba'])) #简单封装一下而已
#找到字符串的最长的无重复子串.
def main(s):
#显然动态规划啊
def solve(s,i):
#返回s从0到i的这个子问题的结果.必须取到i.
#做了这么多子串问题,经典的套路就是子问题加一个条件尾巴必须取到这个index
if i==0:
return s[0]
old =solve(s,i-1)
if s[i] not in old:
return old+s[i]
else:
old=old[old.index(s[i])+1:]
return old+s[i]
tmp=[]
for i in range(len(s)):
tmp.append(solve(s,i))
out=tmp[0]
for i in tmp:
if len(i)>len(out):
out=i
return out
print(main('aabcbabcdefg'))
#书上给的方法:用相同字符出现的index相减即可.其实非常难懂.关键是这个pre,总之非常巧妙!!!!!!!!!!
#pre表达的是上一个无重复字符串的最后一个index的位置.
def main(s):
map=[-1]*256
len1=0
pre=-1
tmp=0
for i in range(len(s)):
tmp=ord(s[i])
pre=max(pre,map[tmp])
cur=i-pre
len1=max(len1,cur)
map[tmp]=i
return len1
print(main('aabcbabcdefg'))
#最小包含子串的长度
def main(s1,s2):
for i in range(len(s2)):
if s2[i] not in s1:
return 0
#按照书上写的:设置一个统计量的哈希表.然后滑动窗口.需要就右华东,多了就做滑动
memo={}
for i in s2:
if i in memo:
memo[i]+=1
else:
memo.setdefault(i,1)
left=0
right=0
match=len(s2)
out=float('inf')
while right<len(s1):
if s1[right] in s2 and memo[s1[right]]>0:
memo[s1[right]]-=1
match-=1
if match==0:#用match来判断是否已经匹配好了
#这时候说明已经匹配好了开始left右移动
while match==0:
tmp=right-left
out=min(out,tmp)
left+=1
#后面太难了先不写了
#第六章:大数据和空间限制
'''
认识布隆过滤器:
想要实现一个网页过滤系统,可以查询url是否出现在网络的黑名单上.
就是多个哈希函数取交
'''
'''
只用2GB内存在20亿个数里面找到出现次数最多的数
2GB存多少32位的数一个数是4byte.2gb=2*2^30
存2^29次幂个数也就是5亿.
哈希分桶法:
20亿个数取mod 10这个哈希函数,这样就分好桶了.数字一样肯定会跑同一个桶
里面,这样每一个桶.里面你统计次数即可,用一个哈希map来统计即可.之后,返回
每一个桶里面频率最高的数,在10个数里面再比一次即可.
'''
'''
40亿个非负整数里面找到没出现的数
内存1GB
用bitmap即可:
32位无符号数是43亿个,43亿个位的这个整数需要43亿/8/10^3 个GB
也就是0.5个GB就够了.
进阶问题:
内存只有10mb,10mb存bitmap可以存多少位.
10*10^6*8=8千万位. (因为一个byte 8位)
需要64个桶即可.
'''
'''
一致性哈希算法:
集群的策略:
在数据库上面的应用:
1.无论是添加删除还是查询数据,都是先把数据的id哈希一下,变成一个
哈希值.
2.如果有N太计算机,就mod n之后,给这个标号的计算机来实现这个操作
这个需要一致性哈希算法,使用这个算法,当添加删除机器时候不用重新
算哈希值.
'''
'''
不用额外空间交换2个整数的值
'''
def main(a,b):
a=a^b
b=a^b
a=a^b
return a,b
print(main(3,5))
#如何记忆这个代码:a^b返回a和b不同的信息,也就是体现的是哪些位a和b不同
#b=a^b这个代码表示把b跟上面的a和b不同信息再取不同.所以b返回的就是原始的a
#(上面这句话怎么看?按照每一个位来看才行.对于一个位我们最后要的是
'''
如果a跟b这个位置不一样,我们就取1,b在这个位置取0,我们就取1,也就是这个位置
取跟b不一样的,那么跟a一样么.a,b已经不一样了,所以这个位置取得就是需要的1)
反之,如果a和b这个位置取得一样,那么取得还是a
'''
'''
在一个其他数都出现k次的数组中找到只出现一次的数(这个数只有一个)
每一个数都转化为k进制之后,做无进位的加法.也就是每个数位分开累加
'''
'''
第八章:
转圈打印矩阵
'''
#每次打印第一行,然后去掉第一行,左旋转90度即可.(转90度,转置后,[::-1])
print('第八章')
def main(a):
import numpy as np
a=np.array(a)
out=[]
while len(a[0])>0:
for i in a[0]:
out.append(i)
a=a[1:]
a=a.T
a=a[::-1]
return out
print(main([[1,2,89],[22,5,65767],[5454,454,454]]))
#找到无序数组中最小的k个数
'''
用大根堆即可.比大根堆的堆定还大就扔了,比堆顶小就插入堆中
'''
#在数组中找到出现次数大于N/K的数
#用哈希表肯定可以但是这里面用另外一个技巧来解.
#这个方法在不看数组内容的情况下判定是否有这样的数,投票问题.
def main(l):
#先解决在数组中找到出现次数大于一半的数,这个问题
#按照顺序读生成cand,如果下一个数根cand一样就跳过,不一样就改cand为*
cand=l[0]
for i in range(1,len(l)):
if cand=='*':
cand=l[i]
continue
if l[i] !=cand:
cand='*'
#然后再遍历一次看cand的数量即可
if cand=='*':
return 0
else:
count=0
for i in range(len(l)):
if l[i]==cand:
count+=1
if count>len(l)//2:
return cand
else:
return 0
print(main([1,2,3,3,3]))
#进阶问题:如果是在数组中找到出现次数大于N/K的数怎么做?
#判定k次,
#最长的可整合子数组的长度.
def main(l):
l.sort()
#遇到间隔就加新开一个数组
out=[]
for i in range(1,len(l)):
if l[i]-l[i-1]!=1:
out.append(i)
last=[0]
out.append(len(l))
last+=out
out=[]
for i in range(len(last)-1):
out.append(l[last[i]:last[i+1]])
outt=[]
for i in out:
if len(i)>len(outt):
outt=i
return outt
print(main([1,3,4,5,6,25,10,34,56,7]))
#为排序正数数组中累加和为指定值的最长子数组的长度.
print('888888888888')
'''
子数组问题动态规划用双指针来描述
'''
def main(arr,target):#子数组取left到right时候的答案
left=right=0
tmp=arr[left:right+1]
out=0
while left!=len(arr)-1 :
tmp=arr[left:right+1]
#这题目的判定很费劲
if sum(tmp) < target and right<len(arr)-1:
right+=1
continue
if sum(tmp)==target and right<len(arr)-1:
now=right-left+1
out=max(out,now)
right+=1
continue
if sum(tmp)>target:
left+=1
continue
if sum(tmp) < target and right>=len(arr)-1:
break
if sum(tmp)==target and right>=len(arr)-1:
now=right-left+1
out=max(out,now)
left+=1
continue
return out
print(main([1,2,1,1,1,1,1,1,4,0.5,0.5,1,0.5,0.5],3))
#未排序数组中累加和为特定值的最长子数组系列问题!非常经典的哈希表题目!!!!
'''
先构造一个sum数组.然后利用哈希表方法来找长度即可.
'''
def main(l,target):
sum=[]
tmp=0
for i in range(len(l)):
tmp+=l[i]
sum.append(tmp)
#对于sum中每一个数值,简历一个字典,字典中key为sum中值,value为这个值第一次
#出现对应的index,所以下面必须是找sum[i]-target即可.
sum=[0]+sum #0表示什么都不选
dicme={}
for i in range(len(sum)):
if sum[i] in dicme:
continue
else:
dicme[sum[i]]=i
print(sum)
print(dicme)
#对于sum中每一个数值,找数值-target是否存在,如果存在就是这两个index相减+1即可.
out=[]
for i in range(len(sum)):
if sum[i]-target in dicme and dicme[sum[i]-target]<=i:
j=dicme[sum[i]-target]
out.append(i-j)
return max(out)
print(main([1,2,-1,-1,-1],-3)) #返回3
'''
这里有人问孔子“以德报怨,何如?”等于提到道家的思想。孔子的答复,也没有直接反对,
只是在逻辑上作一个论辩。他说,别人对我不起,我对他好;那么人家对我好,我又该怎样
报答呢?所以他下面就主张“以直报怨”,以直道而行。是是非非,善善恶恶,
对我好的当然对他好,对我不好的当然不理他,这是孔子的思想。他是主张明辨是非的。
偶然听到诗词大会朱熹说孔孟之道好的一个诗词.又想到了这句话,这句经常被心灵鸡汤曲解
的话.以德报怨显得多迂腐,以直报怨才是孔子推崇的.孔子强就强在不趋炎附势于心灵鸡汤,
而是真正讲解处事道理.
说到狼性和羊性.一代一代的鸡汤害了多少人处事的道理,还一直以为自己是圣人,到死都不知道
为什么别人对自己怎么总是不如自己对别人.你做事标准都没有统一,对你好不好,你都一样对我
我凭什么对你好.中国几千年文化,小学语文课本就一直给人洗脑要做圣人,到头来我也只看到
中国屈辱史而已.在中国说实话很难,鸡汤思想已经根深蒂固了,有些东西你懂了也不能说,因为
跟主流价值观不同,大家会鄙视你不高尚.而事实是大家永远记住的是你是否成功,而不是手段.
'''
#在数组中找到一个局部最小的位置,效率logN
def main(s):
#因为只需要找到一个位置即可.所以用二分法.
if len(s)==2:
if s[0]<s[1]:
return 0
if s[0]==s[1]:
return False
else:
return 1
if len(s)==1 or len(s)==0:
return False
else:
first=0
end=len(s)-1
mid=(first+end)//2
while mid !=0 and mid!=len(s)-1:
if s[mid]<s[mid-1]:
if s[mid]<s[mid+1]:
return mid
else:
first=mid
else:
end=mid
mid=(first+end)//2
if mid==0:
return 0
else:
return len(s)-1
print(main([20,4,-9,-97,0]))
#双函数交替递归的经典例题.
#数组中子数组的最大累乘积.#把下面代码改成动态规划即可,或者记忆体也行.
def mainMax(l,a):#返回数组的子数组以index a为结尾时候最大的累乘积.
if a==0:
return l[0]
return max(l[a],mainMax(l,a-1)*l[a],mainMin(l,a-1)*l[a])
def mainMin(l,a):
if a==0:
return l[0]
return min(l[a],mainMax(l,a-1)*l[a],mainMin(l,a-1)*l[a])
def mainn(l):
a=len(l)-1
out=[]
for i in range(a):
out.append(mainMax(l,i))
return max(out)
print(mainn([-2.5,4,0,3,0.5,8,-1]))
#不包含本位置的累乘数组
#不可以使用除法.
'''
例如arr=[2,3,1,4] 返回[12,8,24,6]
辅助数组的方法:
'''
def main(l):
if len(l)==1:
return l
else:
l1=[1]
for i in range(len(l)):
l1.append(l1[-1]*l[i])
l1=l1[1:]
tmp=l[::-1]
l2=[1]
for i in range(len(tmp)):
l2.append(l2[-1]*tmp[i])
l2=l2[1:]
#l1,l2分别表示从左到右累乘,和从右到左累乘
out=[]
print(l1,l2)
for i in range(len(l)):
if i==0:
out.append(l2[-2])
continue
if i==len(l)-1:
out.append(l1[-2])
continue
else:
out.append(l1[i-1]*l2[i-1])
continue
return out
print(main([1,3,1,2]))
#第九章:其他题目:
'''
从5随机到7随机.
'''
#答案非常牛逼,还是看书吧!P391
#阶乘问题:
#1.阶乘有多少个0
def main(n):
i=1
out=0
while n//5>=1:
out+=n//5
n=n//5
return out
print(main(25))
#一个点是否在三角形内部
'''
如何判断一个边在另一个边的左边还是右边,用向量积的正负来判断.
'''
'''
折纸问题:
'''
'''
关于ide问题:
写脚本比如python程序,做题这种.还是用sublime方便.
spyder的好处是可以分块运行#%%就可以把程序切块.这对于深度学习很方便.节约了时间
但是spyder对于多线程,多进程什么的有bug.
调试还是vs2017好,对于类对象都能清晰的显示.
'''
print('邮局选址问题')
'''
邮局选址问题:
比如数轴上arr=[1,2,3,4,5,100], num=2
建立2个邮局那么需要建在3,100这2个位置上才行.
'''
#首先解决一个问题:如果在arr[i...j]上只能建一个邮局,这个区域上的居民都前往这个邮局
#那么应该建到什么地方.
import copy
def main(arr,num):
#ww的初始化
w=[0]*(len(arr)+1)
ww=[copy.deepcopy(w) for i in range(len(arr)+1)]
#ww[i][j]表示arr[i...j]这个数组上如果只放入一个邮局,那么最短距离是多少.
for i in range(len(arr)):
for j in range(i+1,len(arr)):#只有对角线往上的才有意义,所以从i+1开始算
ww[i][j]=ww[i][j-1]+arr[j]-arr[(i+j)//2]
#上面这个公式怎么理解呢?
'''
证明:其实就是分类讨论,这个问题选中位数显然从i到j的中位数要选择的是(i+j+1)//2
这个点,因为这个点就是中间点偏右的这个点.(即偶数就是中间偏右的,奇数就是正好中间点)
分两种情况看这个公式,第一种是新加入点arr[j]后,中心点不用移动,那么显然整体路程新
加的距离就是arr[j]跟原来中间点的距离也就是arr[(i+j)//2].
第二种情况是新加入点arr[j]后,中心点需要右移动,这种情况发生在j-1时候数组是奇数个
元素,这时候之前的偶数个数组分布是k个,1个中心再k个元素,中心点移动之后左边和中心每一个都
增加距离arr[旧中心点+1]-arr[旧中心点],而右边k个数都减少arr[旧中心点+1]-arr[旧中心点]
新加入的j点增加的距离是arr[j]-arr[旧中心点+1].
综合起来发现移动不移动中心点都可以用上面这个公式来计算w[i][j]
证毕.
'''
#dp[a][b]表示如果在arr[0...b]上建设a+1个邮局,最短距离是多少.
w=[0]*(len(arr))
dp=[copy.deepcopy(w) for i in range(num)]
for i in range(len(w)):
dp[0][i]=ww[0][i]
#动态规划:
for i in range(1,(num)):
for j in range(i+1,len(arr)):
dp[i][j]=float('inf')#先把所有点都改成无穷
for k in range(j):
#k是新的邮局的切分点
dp[i][j]=min(dp[i][j],dp[i-1][k]+ww[k+1][j])
return dp[num-1][len(arr)-1]
print(main([1,2,3,4,5,1000],2)) #完美得到6了
hebing 区间
'''
[编程题] 合并区间
时间限制:1秒
空间限制:131072K
用x,y表示一个整数范围区间,现在输入一组这样的范围区间(用空格隔开),请输出这些区间的合并。
输入描述:
一行整数,多个区间用空格隔开。区间的逗号是英文字符。
输出描述:
合并后的区间,用过空格隔开,行末无空格
输入例子1:
1,3 2,5
输出例子1:
1,5
输入例子2:
1,3 2,5 8,10 11,15
输出例子2:
1,5 8,10 11,15
'''
#可算过了,rstrip是因为测试用例里面有bug,多给了一个空格.
a=input()
a=a.rstrip(' ').split(' ')
if a!=['']:
for i in range(len(a)):
tmp=a[i].split(',')
a[i]=[int(tmp[0]),int(tmp[1])]
a=sorted(a)
def panding(a):
for i in range(len(a)-1):
j=i+1
if a[i][1]>=a[j][0] and a[i][1]<a[j][1]:
tmp=a[:i]
tmp.append([a[i][0],a[j][1]])
tmp+=a[j+1:]
return tmp
if a[i][1]>=a[j][1]:
return a[:j]+a[j+1:]
return a
while len(panding(a))!=len(a):
a=panding(a)
tmp=''
for i in a:
tmp+=str(i[0])+','+str(i[1])+' '
print(tmp[:-1])
else:
print('')