数组元素分类聚合,譬如给出数组[1 3 1 4 0],找出所有小于k的元素,并通过对换数组的元素,使所有小于k的元素聚集在一起,问最少要调换几次?如本例中,若k=2,则将1和4对换或将0和3对换,都能达到目的,即最少对换一次 思路:找出一个长度等于数组中小于k的元素个数的滑窗,这个滑窗中不小于k的元素个数最少
#华为机试第二题:
import sys
for line in sys.stdin:
s=line.strip().split()
sint=list(map(int,s)) #把元素都转成数字
cnt=0
k=int(input())
for i in sint:
if i<k:
cnt+=1 #先找出所有小于k的元素个数,即滑窗的长度
minx=cnt;left=right=tarcnt=0
while right<len(s):
if sint[right]>k: #元素从右边进入滑窗,判断新进的元素是否比k大
tarcnt+=1
if (right-left+1)==cnt: #判断滑窗大小是否已经丰满
minx=min(minx,tarcnt) #只存储较小的值
left+=1 #滑窗左边界右移
if sint[left-1]>k: #右移要注意是否把目标元素移出去了
tarcnt-=1 #若移出去了要及时更新计数器
right+=1 #滑窗右边界右移
print(minx) #输出结果
变种,充分利用python的切片及count方法优势
import sys
for line in sys.stdin:
s=line.strip().split()
sint=list(map(int,s))
cnt=0
k=int(input())
for i in range(len(sint)):
if sint[i]<k:
cnt+=1 #先找出所有小于k的元素个数,即滑窗的长度
else:
sint[i]=k+1 #把所有不小于k的元素统一成一个大值方便下面用count方法
minx=cnt;left=tarcnt=0
while left<len(s)-cnt: #不用像上面那么麻烦,直接利用切片功能
tarcnt=(sint[left:left+cnt].count(k+1))#也不用一个个判断,直接用count方法
minx=min(minx,tarcnt)#只存储较小的值
left+=1 #窗口右移
print(minx)