华为面试题(笔试,8分钟写出代码)

2025年3月27日:今天看到这个问题的解答,感觉到有些逻辑不是很顺,于是又整理的了一下,代码中内层循环的执行逻辑,可以用文末的数学推导来解释。

除此之外,在使用deepseek来分析这段代码的时候,它提出这个解答方法属于贪心算法的范畴,会陷入局部最优解的问题,但是deepseek却举不出来相应的示例来反正这个问题。可能确实也有这种情况,元素的顺序不同,得到的最终结果也不同。如果有大佬刷到,还请多多指点。

===========================2017年的问题====================================

题目:有两个数组a,b,大小都为n,数组元素的值任意,无序; 要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小 

先上代码
java代码:
public class MinDiff {
    public static void main(String[] args){
        int[] aa={2,5,4,3,1,0};
        int[] bb={7,9,8,10,6,11};
        exchange(aa,bb);

    }
    static void exchange(int[] a,int[] b){

        int n=a.length;
        int diff=0;
        for(int i=0;i<n;i++){
            diff+=a[i]-b[i];//计算两组数的差
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                int tp=a[i]-b[j];//计算两组数中单个元素的差值
                int t=tp-diff;//单个元素差值和数组的差值比较
                if(t*tp<0){    //以此条件判断是否需要交换
                    int ex=a[i];
                    a[i]=b[j];
                    b[j]=ex;
                    diff-=2*tp;//计算数据交换后两个数组的差值
                }
            }
        }
        for(int i=0;i<n;i++){
            System.out.println(a[i]+" "+b[i]);
        }
    }
}
前两天在“算法与数据结构”微信公众号上看到了这一题,当时看了下面的评论,感觉我如果一直不准备这方面的知识,我估计也会首先想到排序。
但是,这题说数据是无序的所以排序一定不是正确的方法。我的想法也不是一气呵成的,算是一点点试出来的。以下是我的思路。
首先,把问题简化,如果a,b两个数组长度为2,这题怎么做(别排序)取a={1,2},b={5,3}?
我的思路:
	1、分别计算a、b两个数组的元素之和suma和sumb,并求他们的差diff=suma-sumb(这里diff=-5);
	2、对单个元素进行操作,a[0]-b[0]=1-5=-4,这里a[0]和b[0]的差值小于a数组和b数组整体的差,交换他们,此时,a={5,2},b={1,3},diff=3;
 
	然后继续a[0]-b[1]=5-3=2,2<3=diff,交换a[0]和b[1],此时a={3,2},b={1,5},差值为diff=-1.到此,一次循环结束。
	3、按照步骤2的方法,把数组a的元素从头到尾和b数组中所有元素比较,直到最后一个数组元素。
以上就是我的思路。这里还有个问题:如何保证交换后两数组的差值一定会减小?
我们设diff为数组和的差,singlediff表示单个元素的差。我们先列举几种情况:
	1、diff=-5,singlediff=-4
	2、diff=-5,singlediff=-7
	3、diff=-5,singlediff=4
	4、diff=5,singlediff=-4
	5、diff=5,singlediff=7
	6、diff=5,singlediff=4
关于差值的情况我们举出来了,但是问题的关键是如何求数据交换后的新的差值newDiff?
就像代码里那样:newDiff=diff-2*singlediff
用上面6组数据带入求newDiff然后就能得到规律:(singlediff-diff)*single<0时交换数据可以保证交换后的差值diff一定减小。
代码思路到此为止。

=============================2025年3月27日=================================

数学推导:交换条件的统一证明

1. 定义变量

设当前两数组和的差值为:

diff=sum(A)−sum(B)

设待交换元素对的差值为:

Δ=a[i]−b[j]

2. 交换后的差值变化

交换元素后,新差值为:

diffnew=diff−2Δ

3. 优化目标

我们希望交换后的绝对差值减小,即:

∣diffnew∣<∣diff∣

4. 平方差推导

考虑差值平方的变化:

5. 交换条件

要使绝对差值减小,需要:

4Δ(Δ−diff)<0

即:

Δ(Δ−diff)<0

6. 条件解释

该条件表示:

  • 当 Δ 和 (Δ−diff) 异号时,交换有效

  • 这意味着 Δ 必须位于 0 和 diff 之间

7. 示例验证

以初始差值 diff=−5为例:

检验交换 Δ=−4:

(−4)×(−4−(−5))=(−4)×1=−4<0

计算实际差值变化:

验证通过,交换确实减小了绝对差值。

8. 结论

通过平方差方法,我们统一推导出交换条件:

(a[i]−b[j])(a[i]−b[j]−diff)<0

该条件确保每次交换都严格减小两数组和的绝对差值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值