数组
一.如何找出数组中唯一的重复元素
1.空间换时间法
def FindDup(arr):
if arr==None:
return -1
lens=len(arr)
hashTable=dict()
i=0
while i<lens-1:
hashTable[i]=0
i+=1
j=0
while j<lens:
if hashTable[arr[j]-1]==0:
hashTable[arr[j]-1]=arr[j]-1
else:
return arr[i]
j+=1
return -1
if __name__=="__main__":
arr=[1,3,4,2,5,3]
print(FindDup(arr))
3
2.累加求和法
def FindSum(arr):
if arr==None:
return -1
length=len(arr)-1
i=0
sum=0
while i<len(arr):
sum+=arr[i]
i+=1
while length!=0:
sum-=length
length-=1
return sum
if __name__=="__main__":
arr=[1,3,4,2,5,3]
print(FindSum(arr))
3
3.异或法
def FindOr(arr):
if arr==None:
return -1
lens=len(arr)
result=0
i=0
while i<lens:
result^=arr[i]
i+=1
j=1
while j<lens:
result^=j
j+=1
return result
if __name__=="__main__":
arr=[1,3,4,2,5,3]
print(FindOr(arr))
3
4.数据映射法
def FindDup(arr):
if arr==None:
return -1
lens=len(arr)
i=0
index=0
while True:
if arr[i]>=lens:
return -1
if arr[index]<0:
break
arr[index]*=-1
index=-1*arr[index]
if index>=lens:
print("数组中有非法数字")
return -1
return index
if __name__=="__main__":
arr=[1,3,4,2,5,3]
print(FindDup(arr))
3
5.环形相遇法
二.如何查找数组中元素的最大值和最小值
1.蛮力法
2.分治法
class MaxMin:
def __init__(self):
self.max=None
self.min=None
def getMax(self):
return self.max
def getMin(self):
return self.min
def Getmaxmin(self,arr):
if arr==None:
print("数组为空")
return
lens=len(arr)
self.max=arr[0]
self.min=arr[0]
i=0
while i<(lens-1):
if arr[i]>arr[i+1]:
tmp=arr[i]
arr[i]=arr[i+1]
arr[i+1]=tmp
i+=2
self.min=arr[0]
i=2
while i<lens:
if arr[i]<self.min:
self.min=arr[i]
i+=2
self.max=arr[1]
i=3
while i<lens:
if arr[i]>self.max:
self.max=arr[i]
i+=2
if lens%2==1:
if self.max<arr[lens-1]:
self.max=arr[lens-1]
if self.min>arr[lens-1]:
self.min=arr[lens-1]
if __name__=="__main__":
arr=[7,3,19,40,4,7,1]
m=MaxMin()
m.Getmaxmin(arr)
print("Max:",m.getMax())
print("Min:",m.getMin())
Max: 40
Min: 1
3.变形的分治法
class MaxMin:
def getMaxMin(self,arr,start,end):
if arr==None:
print("数组为空")
return
list=[]
m=int((start+end)/2)
if start==end:
list.append(arr[start])
list.append(arr[start])
return list
if start+1==end:
if arr[start]>=arr[end]:
max=arr[start]
min=arr[end]
else:
max=arr[end]
min=arr[start]
list.append(min)
list.append(max)
lList=self.getMaxMin(arr,start,m)
rList=self.getMaxMin(arr,m+1,end)
max=lList[1] if (lList[1]>rList[1]) else rList[1]
min=lList[0] if (lList[0]<rList[0]) else rList[0]
list.append(min)
list.append(max)
return list
if __name__=="__main__":
arr=[7,3,19,40,4,7,1]
m=MaxMin()
result=m.getMaxMin(arr,0,len(arr)-1)
print("Max:", result[1])
print("Min:", result[0])
Max: 40
Min: 1
三.如何找出旋转数组的最小元素
def GetMin_1(arr,low,high):
if high<low:
return arr[0]
if high==low:
return arr[low]
mid=int(low+((high-low)/2))
if arr[mid]<arr[mid-1]:
return arr[mid]
elif arr[mid+1]<arr[mid]:
return arr[mid+1]
elif arr[high]>arr[mid]:
return GetMin_1(arr,low,mid-1)
elif arr[mid]>arr[low]:
return GetMin_1(arr,mid+1,high)
else:
return min(GetMin_1(arr,low,mid-1),GetMin_1(arr,mid+1,high))
def Getmin(arr):
if arr==None:
print("数组为空")
return
else:
return GetMin_1(arr,0,len(arr)-1)
if __name__=="__main__":
arr1=[5,6,1,2,3,4]
min1=Getmin(arr1)
print(min1)
arr2=[1,1,0,1]
min2=Getmin(arr2)
print(min2)
1
0
def swap(arr,low,high):
while low<high:
tmp=arr[low]
arr[low]=arr[high]
arr[high]=tmp
low+=1
high-=1
def RotateArr(arr,div):
if arr==None or div<0 or div>=len(arr):
print("参数不合法")
return
if div==0 or div==len(arr)-1:
return
swap(arr,0,div)
swap(arr,div+1,len(arr)-1)
swap(arr,0,len(arr)-1)
if __name__=="__main__":
arr=[1,2,3,4,5]
RotateArr(arr,2)
i=0
while i<len(arr):
print(arr[i],end=" ")
i+=1
4 5 1 2 3
四.如何找出数组中丢失的数
1.累加求和
def GetNum(arr):
if arr==None or len(arr)<=0:
print("参数不合理")
return
suma=0
sumb=0
i=0
while i<len(arr):
suma+=arr[i]
sumb+=i
i+=1
sumb+=len(arr)+len(arr)+1
return sumb-suma
if __name__=="__main__":
arr=[1,4,3,2,7,5]
print(GetNum(arr))
6
2.异或法
def GetNum(arr):
if arr==None or len(arr)<=0:
print("参数不合理")
return
a=arr[0]
b=1
length=len(arr)
i=1
while i<length:
a=a^arr[i]
i+=1
i=2
while i<=length+1:
b=b^i
i+=1
return a^b
if __name__=="__main__":
arr=[1,4,3,2,7,5]
print(GetNum(arr))
6
五.如何找出数组中出现奇数次的数
1.字典法
def get2Num(arr):
if arr==None or len(arr)<1:
print("数组为空")
return
dic=dict()
i=0
while i<len(arr):
if arr[i] not in dic:
dic[arr[i]]=1
else:
dic[arr[i]]=0
i+=1
for k,v in dic.items():
if v==1:
print(k,end=" ")
if __name__=="__main__":
arr=[3,5,6,6,5,7,2,2]
get2Num(arr)
3 7
2.异或法
def Get2num(arr):
if arr==None or len(arr)<1:
print("参数不合理")
return
result=0
position=0
i=0
while i<len(arr):
result=result^arr[i]
i+=1
tmpResult=result
i=result
while i&1==0:
position+=1
i=i>>1
i=1
while i<len(arr):
if (arr[i]>>position)&1==1:
result=result^arr[i]
i+=1
print(result)
print(result^tmpResult)
if __name__=="__main__":
arr=[3,5,6,6,5,7,2,2]
Get2num(arr)
3
7
六.如何找出数组中第k小的数
1.排序法
2.部分排序法
3.类快速排序方法
七.如何求数组中两个元素的最小距离
1.蛮力法
import sys
def minDistance(arr,num1,num2):
if arr==None or len(arr)<=0:
print("数组为空或不合理")
return -1
minDis=sys.maxsize
dist=0
i=0
while i<len(arr):
if arr[i]==num1:
j=0
while j<len(arr):
if arr[j]==num2:
dist=abs(i-j)
if dist<minDis:
minDis=dist
j+=1
i+=1
return minDis
if __name__=="__main__":
arr=[4,5,6,4,7,4,6,4,7,8,5,6,4,3,10,8]
num1=4
num2=8
print(minDistance(arr,num1,num2))
2
2.动态规划
八.如何求解最小三元组距离
九.如何求数组中绝对值最小的数
1.顺序比较法
import sys
def FindMin(arr):
if arr==None or len(arr)<=0:
print("输入参数不合理")
return
mins=sys.maxsize
i=0
while i<len(arr):
if abs(arr[i])<abs(mins):
mins=arr[i]
i+=1
return mins
if __name__=="__main__":
arr=[-10,-5,-2,7,15,50]
print("绝对值最小的数为:"+str(FindMin(arr)))
绝对值最小的数为:-2
2.二分法
def FindMin(arr):
if arr==None or len(arr)<=0:
print("输入参数不合理")
return
length=len(arr)
if arr[0]>=0:
return arr[0]
if arr[length-1]<=0:
return arr[length-1]
mid=0
begin=0
end=length-1
absMin=0
while True:
mid=int(begin+(end-begin)/2)
if arr[mid]==0:
return 0
elif arr[mid]>0:
if arr[mid-1]>0:
end=mid-1
elif arr[mid-1]==0:
return 0
else:
break
else:
if arr[mid+1]<0:
begin=mid+1
elif arr[mid+1]==0:
return 0
else:
break
if arr[mid]>0:
if arr[mid]<abs(arr[mid-1]):
absMin=arr[mid]
else:
absMin=arr[mid-1]
else:
if abs(arr[mid])<arr[mid+1]:
absMin=arr[mid]
else:
absMin=arr[mid+1]
return absMin
if __name__=="__main__":
arr=[-10,-5,-2,7,15,50]
print("绝对值最小的数为:"+str(FindMin(arr)))
绝对值最小的数为:-2
十.如何求数组连续最大和
1.蛮力法
def MaxSubArray(arr):
if arr==None or len(arr)<1:
print("参数不合法")
return
ThisSum=0
MaxSum=0
i=0
while i<len(arr):
j=i
while j<len(arr):
ThisSum=0
k=i
while k<j:
ThisSum+=arr[k]
k+=1
if ThisSum>MaxSum:
MaxSum=ThisSum
j+=1
i+=1
return MaxSum
if __name__=="__main__":
arr=[1,-2,4,8,-4,7,-1,-5]
print("绝对值最小的数为:"+str(MaxSubArray(arr)))
绝对值最小的数为:15
2.重复利用已经计算的子数组和
import sys
def MaxSubArray(arr):
if arr==None or len(arr)<1:
print("参数不合法")
return
maxSum=-sys.maxsize-1
i=0
while i<len(arr):
sums=0
j=i
while j<len(arr):
sums+=arr[j]
if sums>maxSum:
maxSum=sums
j+=1
i+=1
return maxSum
if __name__=="__main__":
arr=[1,-2,4,8,-4,7,-1,-5]
print("绝对值最小的数为:"+str(MaxSubArray(arr)))
绝对值最小的数为:15
3.动态规划方法
def MaxSubArray(arr):
if arr==None or len(arr)<1:
print("参数不合法")
return
length=len(arr)
End=[None]*length
All=[None]*length
End[length-1]=arr[length-1]
All[length-1]=arr[length-1]
End[0]=All[0]=arr[0]
i=0
while i<length:
End[i]=max(End[i-1]+arr[i],arr[i])
All[i]=max(End[i],All[i-1])
i+=1
return All[length-1]
if __name__=="__main__":
arr=[1,-2,4,8,-4,7,-1,-5]
print("绝对值最小的数为:"+str(MaxSubArray(arr)))
绝对值最小的数为:15
4.优化的动态规划方法
def MaxSubArray(arr):
if arr==None or len(arr)<1:
print("参数不合法")
return
nAll=arr[0]
nEnd=arr[0]
i=1
while i<len(arr):
nEnd=max(nEnd+arr[i],arr[i])
nAll=max(nEnd,nAll)
i+=1
return nAll
if __name__=="__main__":
arr=[1,-2,4,8,-4,7,-1,-5]
print("绝对值最小的数为:"+str(MaxSubArray(arr)))
绝对值最小的数为:15
import sys
class Test:
def __init__(self):
self.begin=0
self.end=0
def MaxSubarr(self,arr):
length=len(arr)
maxSum=-sys.maxsize
nSum=0
nStart=0
i=0
while i<length:
if nSum<0:
nSum=arr[i]
nStart=i
else:
nSum+=arr[i]
if nSum>maxSum:
maxSum=nSum
self.begin=nStart
self.end=i
i+=1
return maxSum
def getBegin(self):
return self.begin
def getEnd(self):
return self.end
if __name__=="__main__":
test=Test()
arr=[1,-2,4,8,-4,7,-1,-5]
print("连续最大和为:"+str(test.MaxSubarr(arr)))
print("最大和对应的数组起始与结束坐标分别为:"+str(test.getBegin())+","+str(test.getEnd()))
连续最大和为:15
最大和对应的数组起始与结束坐标分别为:2,5
十一.如何找出数组中出现1次的数
def FindEvenNumber(arr):
newArr=[]
i=0
while i<(len(arr)-1):
number=arr[i]
j=i+1
while j<len(arr):
if number==arr[j]:
newArr.append(number)
j+=1
i+=1
result=list(set(arr)-set(newArr))
return result[0]
if __name__=="__main__":
arr=[6,3,4,5,9,4,3]
print(FindEvenNumber(arr))
9
十二.如何对数组旋转
def RotateArr(arr):
length=len(arr)
i=length-1
while i>0:
row=0
col=i
while col<length:
print(arr[row][col],end=" ")
row+=1
col+=1
print("
")
i-=1
i=0
while i<length:
row=i
col=0
while row<length:
print(arr[row][col],end=" ")
row+=1
col+=1
print("
")
i+=1
if __name__=="__main__":
arr=[[1,2,3],[4,5,6],[7,8,9]]
RotateArr(arr)
3
2 6
1 5 9
4 8
7
十四.如何求集合的所有子集
def GetAllSubset(arr,mask,c):
length=len(arr)
if length==c:
print("{",end=" ")
i=0
while i<length:
if mask[i]==1:
print(arr[i],end=" ")
i+=1
print("}")
else:
mask[c]=1
GetAllSubset(arr,mask,c+1)
mask[c]=0
GetAllSubset(arr,mask,c+1)
if __name__=="__main__":
arr=["a","b","c"]
mask=[0,0,0]
GetAllSubset(arr,mask,0)
{ a b c }
{ a b }
{ a c }
{ a }
{ b c }
{ b }
{ c }
{ }
十五.如何对数组进行循环移位
def RightShift(arr,k):
if arr==None:
print("参数不合法")
return
length=len(arr)
while k!=0:
tmp=arr[length-1]
i=length-1
while i>0:
arr[i]=arr[i-1]
i-=1
arr[0]=tmp
k-=1
if __name__=="__main__":
k=4
arr=[1,2,3,4,5,6,7,8]
RightShift(arr,k)
i=0
while i<len(arr):
print(arr[i],end=" ")
i+=1
5 6 7 8 1 2 3 4
def RightShift(arr,k):
if arr==None:
print("参数不合法")
return
length=len(arr)
k%=length
while k!=0:
tmp=arr[length-1]
i=length-1
while i>0:
arr[i]=arr[i-1]
i-=1
arr[0]=tmp
k-=1
if __name__=="__main__":
k=4
arr=[1,2,3,4,5,6,7,8]
RightShift(arr,k)
i=0
while i<len(arr):
print(arr[i],end=" ")
i+=1
5 6 7 8 1 2 3 4
def Reverse(arr,start,end):
while start<end:
temp=arr[start]
arr[start]=arr[end]
arr[end]=temp
start+=1
end-=1
def RightShift(arr,k):
if arr==None:
print("参数不合法")
return
length=len(arr)
k%=length
Reverse(arr,0,length-k-1)
Reverse(arr,length-k,length-1)
Reverse(arr,0,length-1)
if __name__=="__main__":
k=4
arr=[1,2,3,4,5,6,7,8]
RightShift(arr,k)
i=0
while i<len(arr):
print(arr[i],end=" ")
i+=1
5 6 7 8 1 2 3 4
十七.如何寻找最多的覆盖点
def MaxCover(arr,L):
count=2
maxCount=1
start=0
length=len(arr)
i=0
j=1
while i<length and j<length:
while (j<length) and (arr[j]-arr[i]<=L):
j+=1
count+=1
j-=1
count-=1
if count>maxCount:
start=i
maxCount=count
i+=1
j+=1
print("覆盖的坐标点:")
i=start
while i<start+maxCount:
print(arr[i],end=" ")
i+=1
print("
")
return maxCount
if __name__=="__main__":
arr=[1,3,7,8,10,11,12,13,15,16,17,19,25]
print("最长覆盖点数:"+str(MaxCover(arr,8)))
覆盖的坐标点:
7 8 10 11 12 13 15
最长覆盖点数:7
十八.如何判断请求能否在给定的存储条件下完成
def Swap(arr,i,j):
tmp=arr[i]
arr[i]=arr[j]
arr[j]=tmp
def BubbleSort(R,O):
length=len(R)
i=0
while i<length-1:
j=length-1
while j>i:
if R[j]-O[j]>R[j-1]-O[j-1]:
Swap(R,j,j-1)
Swap(O,j,j-1)
j-=1
i+=1
def Schedule(R,O,M):
BubbleSort(R,O)
left=M
length=len(R)
i=0
while i<length:
if left<R[i]:
return False
else:
left-=O[i]
i+=1
return True
if __name__=="__main__":
R=[10,15,23,20,6,9,7,16]
O=[2,7,8,4,5,8,6,8]
N=8
M=50
scheduleResult=Schedule(R,O,M)
if scheduleResult:
print("按照如下请求序列可以完成:")
i=0
while i<N:
print(str(R[i])+","+str(O[i]),end=" ")
i+=1
else:
print("无法完成调度")
按照如下请求序列可以完成:
20,4 23,8 10,2 15,7 16,8 6,5 9,8 7,6
十九.如何按要求构造新的数组
def Calculate(arrA,arrB):
arrB[0]=1
length=len(arrA)
i=1
while i<length:
arrB[i]=arrB[i-1]*arrA[i-1]
i+=1
arrB[0]=arrA[length-1]
i=length-2
while i>=1:
arrB[i]*=arrB[0]
arrB[0]*=arrA[i]
i-=1
if __name__=="__main__":
arrA=[1,2,3,4,5,6,7,8,9,10]
arrB=[None]*len(arrA)
Calculate(arrA,arrB)
i=0
while i<len(arrB):
print(arrB[i],end=" ")
i+=1
3628800 1814400 1209600 907200 725760 604800 518400 453600 403200 362880
二十.如何获取最好的矩阵链相乘方法
二十一.如何求解迷宫问题
class Maze:
def __init__(self):
self.N=4
def PrintSolution(self,sol):
i=0
while i<self.N:
j=0
while j<self.N:
print(sol[i][j],end=" ")
j+=1
print("
")
i+=1
def isSafe(self,maze,x,y):
return x>=0 and x<self.N and y>=0 and y<self.N and maze[x][y]==1
def GetPath(self,maze,x,y,sol):
if x==self.N-1 and y==self.N-1:
sol[x][y]=1
return True
if self.isSafe(maze,x,y):
sol[x][y]=1
if self.GetPath(maze,x+1,y,sol):
return True
if self.GetPath(maze,x,y+1,sol):
return True
sol[x][y]=0
return False
return False
if __name__=="__main__":
rat=Maze()
maze=[
[1,0,0,0],
[1,1,0,1],
[0,1,0,0],
[1,1,1,1]
]
sol=[
[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0]
]
if not rat.GetPath(maze,0,0,sol):
print("不存在可达的路径")
else:
rat.PrintSolution(sol)
1 0 0 0
1 1 0 0
0 1 0 0
0 1 1 1
二十二.如何从三个有序数组中找出它们的公共元素
def FindCommon(arr1,arr2,arr3):
i=0
j=0
k=0
length1=len(arr1)
length2=len(arr2)
length3=len(arr3)
while i<length1 and j<length2 and k<length3:
if arr1[i]==arr2[j] and arr2[j]==arr3[k]:
print(arr1[i],end=" ")
i+=1
j+=1
k+=1
elif arr1[i]<arr2[j]:
i+=1
elif arr2[j]<arr3[k]:
j+=1
else:
k+=1
if __name__=="__main__":
arr1=[2,5,12,20,45,85]
arr2=[16,19,20,85,200]
arr3=[3,4,15,20,39,72,85,190]
FindCommon(arr1,arr2,arr3)
20 85
二十四.如何对有大量重复的数字的数组排序
class TiNode:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
self.height=self.count=1
class Sort:
def Inorder(self,arr,root,index):
if root!=None:
index=self.Inorder(arr,root.left,index)
i=0
while i<root.count:
arr[index]=root.data
index+=1
i+=1
index=self.Inorder(arr,root.right,index)
return index
def GetHeight(self,node):
if node==None:
return 0
else:
return node.height
def Sort(arr):
data_count=dict()
length=len(arr)
i=0
while i<length:
if str(arr[i]) in data_count:
data_count[str(arr[i])]=data_count.get(str(arr[i]))+1
else:
data_count[str(arr[i])]=1
i+=1
index=0
for key,value in data_count.items():
i=value
while i>0:
arr[index]=key
index+=1
i-=1
if __name__=="__main__":
arr=[15,12,15,2,2,12,2,3,12,100,3,3]
Sort(arr)
i=0
while i<len(arr):
print(arr[i],end=" ")
i+=1
二十五.如何对任务进行调度
def Calculate_process_time(t,n):
if t==None or n<=0:
return None
m=len(t)
proTime=[0]*m
i=0
while i<n:
minTime=proTime[0]+t[0]
minIndex=0
j=1
while j<m:
if minTime>proTime[j]+t[j]:
minTime=proTime[j]+t[j]
minIndex=j
j+=1
proTime[minIndex]+=t[minIndex]
i+=1
return proTime
if __name__=="__main__":
t=[7,10]
n=6
proTime=Calculate_process_time(t,n)
if proTime==None:
print("分配失败")
else:
totalTime=proTime[0]
i=0
while i<len(proTime):
print("第"+str(i+1)+"台服务器有"+str(proTime[i]/t[i])+"个任务,执行总时间为:"+str(proTime[i]))
if proTime[i]>totalTime:
totalTime=proTime[i]
i+=1
print("执行完所有任务所需的时间为:"+str(totalTime))
第1台服务器有4.0个任务,执行总时间为:28
第2台服务器有2.0个任务,执行总时间为:20
执行完所有任务所需的时间为:28
二十六.如何对磁盘分区
def Is_allocable(d,p):
dIndex=0
i=0
while i<len(p):
while dIndex<len(d) and p[i]>d[dIndex]:
dIndex+=1
if dIndex>=len(d):
return False
d[dIndex]-=p[i]
i+=1
return True
if __name__=="__main__":
d=[120,120,120]
p=[60,60,80,20,80]
if Is_allocable(d,p):
print("分配成功")
else:
print("分配失败")
分配成功