准备笔试的题目
●计算置信区间.
●服务器建立接收再多的连接,也只占用一个端口, 理解错误的人要回去补充下基础知识!
多项式 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%
复习经典题目: 感觉这个思想 可以说是双移动指针.来控制数组下表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
''' [编程题] 排序次数 时间限制: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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
''' [编程题] 字符串问题 时间限制: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)
数据库技术的根本目标是要解决数据共享的问题
尽管每个进程都有自己的内存地址,不同的进程可以同时将同一个内存页面映射到自己的地址空间中,从而达到共享内存的目的
经典题目还是不熟练
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
''' 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
很难的走棋问题:思路是逆过来,考虑最后一步你进入时候需要多少粮食,从而可以逆着走到开始
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[编程题] 走格子游戏 时间限制: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))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[编程题] 被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 字典记忆法即可.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[编程题] 牛牛的背包问题 时间限制: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))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[编程题] 迷路的牛牛 时间限制: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进制求解法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
今日头条很精彩的题目: 自己没做出来,看了别人的方法. 学习了.如果取值范围很小,可以考虑遍历取值范围来找!!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[编程题] 编程题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)
奶牛题:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[编程题] 奶牛编号 时间限制: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))
又没做出来,还是基本技能不熟练,看的别人的启发. 关键是重要技能 如何求解两个子串的最长公共子序列不熟练.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[编程题] 平方串 时间限制: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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
''' 最长公共子序列 ''' 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.子串的用==第二个数组最后一个判断!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
''' 最长公共子串 ''' 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))
补括号
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[编程题] 缺失的括号 时间限制: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:
非常牛逼代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
算法竞赛书的题目:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
''' 算法竞赛入门经典(第二版) 表达式树: 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) '''
一个双函数递归,加记忆体的题目
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
''' 程序员面试代码指南 排成一条直线的纸牌博弈问题. 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))
上个题目改成记忆体:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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)))
程序员代码面试指南的部分题目:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# -*- 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 区间
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
''' [编程题] 合并区间 时间限制: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('')