字节跳动面试题.无序数组求最大值

1.对于无序数组a,求a[i]-a[j]的最大值,其中i<j

参考:https://www.cnblogs.com/freedom-wangyb/p/4192611.html

package test;

import java.util.Arrays;

public class FindMax {
    public static void main(String[] args) {
        int[] a = new int[] { 9, 20, 3, 16, 6, 5, 7, 1 };
        System.out.println("a[" + a.length + "]=" + Arrays.toString(a));
        System.out.println("find max of a[i]-a[j],i<j : " + findMax(a));
    }

    public static int findMax(int[] a) {
        // 初始化为最小可能的int值
        int max = Integer.MIN_VALUE;
        // a[i]右边元素中的最小值
        int minRight = a[a.length - 1];
        int tempMax;
        for (int i = a.length - 2; i >= 0; i--) {
            tempMax = a[i] - minRight;
            if (a[i] < minRight) {
                minRight = a[i];
            }
            if (tempMax > max) {
                max = tempMax;
            }
        }
        return max;
    }
}

2.一个乱序数组a[0…n-1],求a[j]-a[i]的最大值,其中i<j

从左往右求下标0到 k - 1 的最小值MIN
从右往左求 下标k到n -1 的最大值MAX

对于每个分割点k都有一个MAX - MIN的值,最后求这个值的最大值即可。

例如数组:4 5 2 6 3 1

K:1 2 3 4 5

MIN: 4 4 2 2 2

MAX:6 6 6 3 1

MAX - MIN,最大的值为6 - 2 = 4, 即为结果

参考:https://www.iteye.com/blog/mars914-1667259


一、观察现象
观察一个数组 int a[] = {5,19,40,2,100,844,12,3,6,8,33,90};
很明显最大差值应该是844-2=842
我们把数组分为前后两部分,分割位置为元素2的后面
数组分为两个子数组:
int a1[] = {5,19,40,2};
int a2[] = {100,844,12,3,6,8,33,90};
2刚好是a1的最小值,844是a2的最大值。

二、解决办法
我们通过一个k值,从头到尾多次分割数组。
分别求出每个k值对应的两个子数组a1的最小值a1_min,a2的最大值a2_max
最大差值就是a2_max-a1_min的最大值
可以通过反证法证明:
就是说 最大差值的时候,
a[i] 一定是前面半段数组的最小值,如果不是最小值,就应该去用那个最小值了。
a[j]一定是后面半部分的最大值,如果不是最大值,就应该去用那个最大值了
所以结果一定出现在当从某个k的下标分割时,后面的最大值减去前面的最小值。
————————————————
版权声明:本文为CSDN博主「我是榜样」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhangpeng_linux/article/details/85858331

//一个乱序数组a[0...n-1],求a[j]-a[i]的最大值,其中i<j
#include <iostream>
using namespace std;

class Solution {
public:
    int GetMax(int array[], int len) {
        int max = array[0];
        for (int i = 1; i < len; ++i) {
            if (array[i] > max) {
                max = array[i];
            }
        }
        return max;
    }

    int GetMin(int array[], int len) {
        int min = array[0];
        for (int i = 1; i < len; ++i) {
            if (array[i] < min) {
                min = array[i];
            }
        }
        return min;
    }

    int GetMaxDiff(int array[], int len) {
        int maxDiff = array[1] - array[0];
        for (int i = 1; i < len; ++i) {
            int min = GetMin(array, i);
            int max = GetMax(array + i, len - i);
            if (maxDiff < (max - min)) {
                maxDiff = max - min;
            }
        }
        return maxDiff;
    }
};

int main()
{
    Solution s;
    int array[] = {0,1,40,2,100,844,12,3,6,8,33,8};
    cout << s.GetMaxDiff(array, sizeof(array)/ sizeof(int));
    return 0;
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值