8、 point 8.1 两数之和等于指定值 class Solution: def twoSum(self , numbers , target ): # write code here n = len(numbers) if n<2: return [] L = sorted(numbers) i = 0 j = n-1 while i<j: if L[i]+L[j]==target: a = numbers.index(L[i]) numbers.pop(a) b = numbers.index(L[j]) if b>=a: b += 1 if a>b: a,b = b,a return a+1,b+1 elif L[i]+L[j]>target: j -= 1 elif L[i]+L[j]<target: i += 1 return [] 8.2 数组中相加和为0的三元组 class Solution: def threeSum(self , num ): # write code here n = len(num) num = sorted(num) print('num=',num) res = [] for i in range(n-2): if num[i]>0: break j = i+1 k = n-1 while j<k: if num[i]+num[j]+num[k]==0: t = [num[i],num[j],num[k]] if t not in res: res.append(t) j += 1 k -= 1 elif num[i]+num[j]+num[k]<0: j += 1 elif num[i]+num[j]+num[k]>0: k -= 1 print('res=',res) return 8.3 数组中未出现的最小正整数 先排序,负值略过,重复略过,按1至N对比,如没有则返回 class Solution: def minNumberdisappered(self , arr ): # write code here L = sorted(arr) L.append(L[-1]+1) #print(L) k = 1 for i in range(len(L)-1): #print('i=',i,'k=',k) if L[i]<0: continue if L[i]==L[i+1]: continue if L[i] != k: break else: k += 1 #print('k=',k) return k 9、 other (array / string / sort) 9.1 字符串的排列 对于已有的每一种排列的每个位置k,插入第i个新数字ss[i],得到一组新排列 class Solution: def Permutation(self, ss): # write code here n = len(ss) if n<=0: return if n==1: return ss ss = list(ss) # 输入转成list(list才有insert方法) out = [] out.append([ss[0]]) # i-1时已有的排列(二维数组) for i in range(1,n): tmp = [] for string in out: # 对于已有的每一种排列 for k in range(len(string)+1): # 当前排列的每个位置k s = string.copy() # 复制当前排列 s.insert(k,ss[i]) # 在复制排列的第k个位置,插入第i个数ss[i] tmp.append(s) # 得到一组新排列加入临时二维数组 out = tmp # 更新i-1时已有的排列 for i in range(len(out)): out[i] = ''.join(out[i]) # 数组合成一个对象用于set()去重,再排序 out = sorted(set(out)) # set的元素只能是单个变量,不能是数组等多变量对象 #print(out) return out 9.2 找出连续最长的数字串 原字符串前后加##,数字改1,其它改0,利用规则找01突变点,存储最长数字串 L = input() L = '#'+L+'#' #print('L=',L) S='' for s in L: if s.isdigit(): S += '1' else: S += '0' #print('S=',S) i_start = 0 i_len = 0 Out = [] for i in range(1,len(S)): if S[i]=='1' and S[i-1]=='0': i_start = i #print('i_start=',i_start) elif S[i]=='0' and S[i-1]=='1': i_end = i #print('i_end=',i_end) if i_end-i_start==i_len: Out.append(L[i_start:i_end]) elif i_end-i_start>i_len: i_len = i_end-i_start Out = [] Out.append(L[i_start:i_end]) #print(i_len) print(''.join(Out)+','+str(i_len)) 9.3 学英语 1、关键是1~3位数的表达,首先考虑1~19,20、30、……90建立字典 2、然后将1~3位填充成3位,再分别考虑每一位是否为0的情况 3、and的位置:百位数个数基数词形式加“hundred”,表示几百,在几十几与百位间加上and 例如:2,648 two thousand six hundred and forty eight D = {'1':'one','2':'two','3':'three','4':'four','5':'five','6':'six','7':'seven','8':'eight','9':'nine','10':'ten', '11':'eleven','12':'twelve','13':'thirteen','14':'fourteen','15':'fifteen','16':'sixteen','17':'seventeen','18':'eighteen','19':'nineteen','20':'twenty', '30':'thirty','40':'forty','50':'fifty','60':'sixty','70':'seventy','80':'eighty','90':'ninety'} def fun(L): n = len(L) #print('LL=',L) #print('nn=',n) out = '' if n==1: out += D[L] elif n==2: if int(L)>=10 and int(L)<=20: # 10-20特例 out += D[L] else : if L[0] != '0' and L[1] == '0': out += D[L] elif L[0] != '0' and L[1] != '0': t = L[0]+'0' out += D[t]+' '+ D[L[1]] else: if L[0] == '0' and L[1] == '0' and L[2] == '0': pass elif L[0] != '0' and L[1] == '0' and L[2] == '0': # 佰 out += D[L[0]]+' hundred' elif L[0] == '0' and L[1] != '0' and L[2] == '0': # 十 #out += 'and ' + D[L[1:3]] out += D[L[1:3]] elif L[0] == '0' and L[1] == '0' and L[2] != '0': # 个 #out += 'and ' + D[L[2]] out += D[L[2]] elif L[0] != '0' and L[1] != '0' and L[2] == '0': # 佰十 out += D[L[0]]+' hundred and '+ D[L[1:3]] elif L[0] != '0' and L[1] == '0' and L[2] != '0': # 佰个 out += D[L[0]]+' hundred and '+ D[L[2]] elif L[0] == '0' and L[1] != '0' and L[2] != '0': # 十个 if int(L[1:])>10 and int(L[1:])<20: # 10-20特例 #out += 'and ' + D[L[1:]] out += D[L[1:]] else: t = L[1]+'0' #out += 'and ' + D[t]+' '+D[L[2]] out += D[t]+' '+D[L[2]] elif L[0] != '0' and L[1] != '0' and L[2] != '0': # 百十个 if int(L[1:])>10 and int(L[1:])<20: # 10-20特例 out += D[L[0]] + ' hundred and ' + D[L[1:]] else : t = L[1]+'0' out += D[L[0]] + ' hundred and ' + D[t]+' '+D[L[2]] return out 9.4 人民币转换 D = {'0':'零','1':'壹','2':'贰','3':'叁','4':'肆','5':'伍','6':'陆','7':'柒','8':'捌','9':'玖'} def f4(L): L = L.zfill(4) #-------------------------------------------------- # 个十百千位分别给单位 T = ['仟','佰','拾',''] out = '' for i in range(4): if L[i] != '0': out += D[L[i]]+T[i] else: out += '零' #-------------------------------------------------- # 最多3个0变为1个0 out = out.replace('零零','零') out = out.replace('零零','零') out = out.replace('壹拾','拾') #-------------------------------------------------- # 结尾1个零删除 if out[-1]=='零': out = out[0:-1] return out 9.5 合法IP & Mask # 识别有效的IP地址和掩码并进行分类统计 def value(S): return int(S[0])*256**3 + int(S[1])*256**2 + int(S[2])*256 + int(S[3]) def bin64(S): b = '' for i in S: b += bin(int(i))[2:].zfill(8) return b def isIp(ip): if len(ip) != 4: return False for i in ip: if not i.isnumeric() or int(i)<0 or int(i)>255: return False return True def isMask(mask): if len(mask) != 4: return False for i in mask: if not i.isnumeric() or int(i)<0 or int(i)>255: return False t = list(map(int,list(bin64(mask)))) a = [] for i in range(len(t)-1): a.append(t[i]-t[i+1]) if a.count(1) == 1 and a.count(0) == 30: return True else: return False 9.6 螺旋矩阵 先做4个子函数fun1-4,再做一个主调fun,运行一次剥离一圈数据,直到矩阵为空 def fun1(matrix): if matrix: return matrix.pop(0),matrix else: return [],[] def fun2(matrix): if matrix: t = [] mat = [] for row in matrix: if row: a = row.pop() t.append(a) mat.append(row) return t,mat else: return [],[] def fun3(matrix): if matrix: return matrix.pop()[::-1],matrix else: return [],[] def fun4(matrix): if matrix: t = [] mat = [] for row in matrix[::-1]: if row: a = row.pop(0) t.append(a) mat.append(row) return t,mat[::-1] else: return [],[] def fun(matrix): if matrix: out1,matrix = fun1(matrix) out2,matrix = fun2(matrix) out3,matrix = fun3(matrix) out4,matrix = fun4(matrix) return out1+out2+out3+out4,matrix else: return [],[] 9.7 容器盛水问题 1、从左向右,从右向左各扫一遍,记住当前最大值, 2、如果当前值小于最大值,则计算水容量,如果当前值大于最大值,则更新最大值 3、对应位置左右扫描取小,即是实际容量, 4、第二次扫描时同时计算容量,少一次遍历 class Solution: def maxWater(self , arr ): # write code here L = arr n = len(arr) if n<3: return 0 i_max = arr[0] w1 = [] for i in range(1,n-1): if L[i]>i_max: i_max = L[i] w1.append(0) else: w1.append(i_max-L[i]) i_max = arr[-1] w2 = [] res = 0 for i in range(n-2,0,-1): if L[i]>i_max: i_max = L[i] else: res += min(w1[i-1],i_max-L[i]) #print(w1) #print(w2) return res 9.8 称砝码 砝码一个个地增加,原集合中每一个重量 + 新砝码重量 = 新增重量集合 n = int(input()) weight = list(map(int,input().strip().split())) num = list(map(int,input().strip().split())) set_old = {0} for i in range(n): for j in range(num[i]): # 按砝码个数依次取 w = weight[i] # 新取砝码的重量 #print(w) set_new = set() for s in set_old: set_new.add(s+w) # 原集合中每一个重量 + 新砝码重量 = 新增重量集合 set_old = set_old | set_new # 新增重量集合与原集合的并集,构成下一次的原集合 print(len(set_old))