3768.固定长度子数组中的最小逆序对数目
难度:困难
问题描述:
给你一个长度为n的整数数组nums和一个整数k。
逆序对是指nums中满足i<j且numsi>numsj的一对下标(i,j)。
子数组的逆序对数量是指该子数组内逆序对的个数。
返回nums中所有长度为k的子数组中的最小逆序对数量。
子数组是数组中一个连续的非空元素序列。
示例1:
输入:nums=3,1,2,5,4,k=3
输出:0
解释:
我们考虑所有长度为k=3的子数组(下面的下标是相对于每个子数组而言的):
3,1,2有2个逆序对:(0,1)和(0,2)。
1,2,5有0个逆序对。
2,5,4有1个逆序对:(1,2)。
所有长度为3的子数组中,最小的逆序对数量是0,由子数组1,2,5获得。
示例2:
输入:nums=5,3,2,1,k=4
输出:6
解释:
只有一个长度为k=4的子数组:5,3,2,1。
在该子数组中,逆序对为:(0,1),(0,2),(0,3),(1,2),(1,3),和(2,3)。
逆序对总数为6,因此最小逆序对数量是6。
示例3:
输入:nums=2,1,k=1
输出:0
解释:
所有长度为k=1的子数组只包含一个元素,因此不可能存在逆序对。
因此最小逆序对数量为0。
提示:
1<=n==nums.length<=105
1<=numsi<=109
1<=k<=n
问题分析:
解决这个问题,只要解决好几个小问题就行了
一是对于一个数组a,统计其逆序对数目
二是对于一个给定的数组nums,将所有长度为k的子数组找出
三剩下的就是对所有长度为k的子数组分别求出其逆序对数目,统计其中数目最小的并输出
具体操作请参考程序内容
程序如下:
python
#统计一个数组中逆序对数目并返回
def get_reverse_pairs(a):
n=len(a)
c=0
for i in range(n-1):
for j in range(i,n):
if a[i]>a[j]:
c+=1
return c
#将一个数组a分解为长度为k的子数组,并以列表的形式返回
def get_k_sub_array_from_a(a,k):
n=len(a)
t=[]
for i in range(n-k+1):
t.append(a[i:i+k])
return t
#主程序
nums=eval(input('pls input nums='))
k=int(input('pls input k='))
t=[]
lxd=get_k_sub_array_from_a(nums,k)
print(f'长度为{k}的子数组有{lxd}')
for i in lxd:
c=get_reverse_pairs(i)
print(f'{i}有{c}个逆序对')
t.append(c)
print(f'最小逆序对数量为{min(t)}')
运行实例一
pls input nums=3,1,2,5,4
pls input k=3
长度为3的子数组有\[3, 1, 2, 1, 2, 5, 2, 5, 4]
3, 1, 2有2个逆序对
1, 2, 5有0个逆序对
2, 5, 4有1个逆序对
最小逆序对数量为0
运行实例二
pls input nums=3,4,2
pls input k=1
长度为1的子数组有\[3, 4, 2]
3有0个逆序对
4有0个逆序对
2有0个逆序对
最小逆序对数量为0
运行实例三
pls input nums=5,3,2,4
pls input k=2
长度为2的子数组有\[5, 3, 3, 2, 2, 4]
5, 3有1个逆序对
3, 2有1个逆序对
2, 4有0个逆序对
最小逆序对数量为0