📌  相关文章
📜  找到修改后的数组的最小值的最大值(1)

📅  最后修改于: 2023-12-03 15:25:50.291000             🧑  作者: Mango

题目描述

给定一个长度为n的未排序数组a,并定义数组变换操作Sw(a,i,j)为将a数组中下标为i和j的元素交换位置,现在对于数组a,我们可以执行任意多次Sw操作,我们希望找到一种操作方案,使得执行完所有操作后,a数组的最小值最大。

请你编写一个函数,输入一维数组a,输出执行操作后的最小值最大值。

思路

首先可以看出本题有两种方式可以做到最优解,即二分查找和贪心算法。

二分查找

因为本题是要找到最小值的最大值,所以需要在一个区间内二分查找最大值。

在判断一个数是否为正解时,可以使用贪心的思路:尽量现在选择排在前面的元素,直到无法交换,再选择排在后面的元素。

具体实现时,可以把所有数初始排序,然后设置low和high两个指针,将low指向最小元素,将high指向最大元素,然后对区间进行二分查找,对于每个mid,都执行一遍上述的贪心算法,直到找到正解或low>high为止。

贪心算法

贪心算法的思路如上所述,先对数组进行排序,再用low和high指向最小元素和最大元素,这时候可以得到一个初步的正解。接着,从元素a[low]开始向后扫描,若a[i]>a[low],则一定可以通过Sw操作将前面的元素和a[i]交换,这样可以得到较小的a[low]和较大的a[i],否则a[low]就不可能再被更改,low指针再向后移动一位。

依此类推,对于所有i>low,如果a[i]>a[low],就尝试进行Sw操作,如果能操作成功,就将low指针后移,否则i指针后移。最终可以得到最小值的最大值。

代码实现
Python
def min_max(a: List[int]) -> int:
    n = len(a)
    a.sort()
    low, high = 0, n-1
    while low < high:
        mid = (low + high + 1) // 2
        if check(a, n, mid):
            low = mid
        else:
            high = mid - 1
    return a[low]

def check(a: List[int], n: int, k: int) -> bool:
    cnt = 0
    i, j = 0, 1
    while i < n and j < n:
        while j < n and a[j] - a[i] <= k:
            j += 1
        cnt += j - i - 1
        i += 1
    return cnt >= n * (n-1) // 4
C++
#include<bits/stdc++.h>
using namespace std;

const int INF=2147483647,N=100010;

int n,a[N],tmax=-INF;

bool check(int x){
    int lw=1,hi=1,add=0,cnt=0;
    if(x<tmax-a[1]) return false;
    for(int i=1;i<n;i++){
        while(hi<n && a[hi+1]<=x+a[i]) hi++;
        cnt+=(hi-lw+add);//2.计算小于等于x的数的个数
        add+=(hi-lw);//3.计算等于x的数的个数
        while(a[i+1]-a[lw]>x) {
            add-=(hi-lw);
            lw++;//4.计算小于等于a[i]的数的个数
        }
    }
    return cnt>=(n-1)*n/4;
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],tmax=max(tmax,a[i]);
    sort(a+1,a+1+n);
    int l=0,r=tmax-a[1]+1,ans;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid)) l=mid+1,ans=mid;//1.使用二分查找
        else r=mid-1;
    }
    cout<<ans;
    return 0;
}
参考资料

最小值的最大值

算法笔记

算法基础课