2.10 寻找数组中的最大值和最小值

来源:互联网 发布:私有云 软件 编辑:程序博客网 时间:2024/05/20 01:39

1. 前言

本文的一些图片, 资料 截取自编程之美

2. 问题描述

这里写图片描述

3. 问题分析

对于这个问题, 我们最常规的思路, 就是 :
解法一 : 就是遍历一次数组, 如果当前元素, 比max大, 或者比min小, 则记录下其值, 通过这样依次遍历, 即找出了数组的最大值和最小值, 这样比较了 (2 * n)次
解法二 : 首先遍历一次数组, 两个相邻的数一组[(0, 1), (2, 3), … ], 将较小者放在左边, 较大者放在右边, 然后min在每一组的左边之中比较, max在每一组的右边之中比较, 如果数组中元素个数为奇数, 则对最后一个元素特殊处理, 最后遍历结果即为所求, 而这样只比较了 (1.5 * n)次, 优化了一些
解法三 : 这个思路和上面是一致的, 不过这里不需要改变原数组的值, 同样两个一组, 保存较小值, 和较大值, 然后小的和min比较, 大的和max比较, 如果数组中元素个数为奇数, 则对最后一个元素特殊处理, 最后遍历结果即为所求
解法四 : 分治思想, 分而制之, 如果, 求解的空间只有一个元素, 则将最大值和最小值均设置为该值 返回, 如果求解的空间有两个元素, 则比较一次, 然后设置较大值和较小值 返回, 这两个条件作为递归结束条件
然后对于 求解空间大于2个元素的情况, 将整个区间分解为两个区间, 递归求解出左边区间的最大值和最小值, 然后递归求解出右边区间的最大值和最小值, 最后合并, 结合左右两边区间的最大值和最小值, 计算出整个区间的最大值和最小值, 求的的结果即为所求

4. 代码

/** * file name : Test16FindMaxAndMin.java * created at : 2:50:14 PM May 23, 2015 * created by 970655147 */package com.hx.test03;public class Test17FindMaxAndMin {    // 寻找最大最小元素    public static void main(String []args) {        int[] intArr = {47, 91, 18, 63, 25, 44, 86, 69, 97, 74, 15, 54, 91, 66, 52, 13, 67, 3, 67, 43, 6, 94, 65, 77, 7, 81, 30, 6, 99, 64 };        findMaxAndMin01(intArr);        findMaxAndMin02(intArr);        findMaxAndMin03(intArr);        findMaxAndMin04(intArr);    }    // 遍历一次arr  分别求min, max    public static void findMaxAndMin01(int[] arr) {        int max, min;        max = min = arr[0];        for(int i=1; i<arr.length; i++) {            if(arr[i] > max) {                max = arr[i];            }            if(arr[i] < min) {                min = arr[i];            }        }        Log.log(min, max);    }    // 预处理arr  将arr以奇偶索引 分为两组 奇数存放较小者  偶数存放较大者    // 在分别在奇数组 求min, 偶数组求max    // 如果数组长度为奇数  则进行最后一个元素的判断    public static void findMaxAndMin02(int[] arr) {        int lastIdx = arr.length - 1;        for(int i=0; i<lastIdx; i+=2) {            if(arr[i] > arr[i + 1]) {                Tools.swap(arr, i, i+1);            }        }        int max = arr[1], min = arr[0];        for(int i=2; i<lastIdx; i+=2) {            if(arr[i] < min) {                min = arr[i];            }            if(arr[i+1] > max) {                max = arr[i+1];            }        }        if((arr.length & 1) == 1) {            if(arr[lastIdx] < min) {                min = arr[lastIdx];            }            if(arr[lastIdx] > max) {                max = arr[lastIdx];            }        }        Log.log(min, max);    }    // 对arr 两个一组进行遍历    // 去较大者和max进行比较  去较小者和min进行比较    // 如果数组长度为奇数  则进行最后一个元素的判断    // 这种方法 不会修改原来的数组    public static void findMaxAndMin03(int[] arr) {        int lastIdx = arr.length - 1;        int max = arr[0], min = arr[0];        int tmp01, tmp02;        for(int i=0; i<lastIdx; i+=2) {            if(arr[i] > arr[i + 1]) {                tmp01 = arr[i];                tmp02 = arr[i+1];            } else {                tmp01 = arr[i+1];                tmp02 = arr[i];            }            if(tmp01 > max) {                max = tmp01;            }            if(tmp02 < min) {                min = tmp02;            }        }        if((arr.length & 1) == 1) {            if(arr[lastIdx] < min) {                min = arr[lastIdx];            }            if(arr[lastIdx] > max) {                max = arr[lastIdx];            }        }        Log.log(min, max);    }    // 分而制之    public static void findMaxAndMin04(int[] arr) {        int[] res = findMaxAndMin040(arr, 0, arr.length-1);        Log.log( res[1], res[0]);    }    // low, high 包括low, high    // 如果low==high  则说明需要findMaxAndMin040的只有一个数字  则令res[0], res[1]均为该数  然后返回    // 否则 如果(low+1)==high  则说明只有两个数字  则令res[0]为较大者, res[1]为较小者    // 否则  对low, high在分成两部分  递归调用findMaxAndMin040  在左半边的结果和右半边的结果中取min, max    private static int[] findMaxAndMin040(int[] arr, int low, int high) {        int[] res = new int[2];        if(low == high) {            res[0] = res[1] = arr[low];            return res;        } else if((low + 1) == high) {            if(arr[low] > arr[low+1]) {                res[0] = arr[low];                res[1] = arr[low+1];            } else {                res[0] = arr[low+1];                res[1] = arr[low];                          }            return res;        }        int len = high - low;        int[] tmp01, tmp02;        if((len & 1) == 1) {            int mid = low + len / 2;            tmp01 = findMaxAndMin040(arr, low, mid);            tmp02 = findMaxAndMin040(arr, mid, high);        } else {            int mid = low + len / 2;            tmp01 = findMaxAndMin040(arr, low, mid);            tmp02 = findMaxAndMin040(arr, mid+1, high);        }        res[0] = (tmp01[0] > tmp02[0]) ? tmp01[0] : tmp02[0];        res[1] = (tmp01[1] < tmp02[1]) ? tmp01[1] : tmp02[1];        return res;    }}

5. 运行结果

这里写图片描述

6. 总结

通常, 对于我来说, 我可能只会使用第一种方法, 哈哈 毕竟太难想了, 但是那些专研算法的大神们, 总是会给我们惊喜, 想到更优的解法, 然后分享出来, 感谢这种思想 free

注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!

0 0
原创粉丝点击