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, 所以请大家指出!
- 2.10 寻找数组中的最大值和最小值
- 2.10 寻找数组中的最大值和最小值
- 2.10 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 1、寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- 寻找数组中的最大值和最小值
- Java基础---包.内部类
- 生命周期及布局
- 个人简历英语词汇大全
- coredata使用代码实现
- 第一篇博客
- 2.10 寻找数组中的最大值和最小值
- O(1)时间删除单向循环链表给定结点
- CentOS系统下的Hadoop集群(第5期)_Hadoop安装配置
- linux lsof 命令
- 二叉树的先序-中序-后序遍历(一)-递归
- Java深度历险(四)Java垃圾回收机制与引用类型
- HDOJ2544(简单最短路)
- poj 2117 Electricity 【无向图求割点】【求去掉一个点后 图中最多的BCC数目】
- CANVAS LMS开源系统