package com.work.home_3_1;
import java.util.Arrays;
/**
* 贪心算法-数列极差问题
* 1. 问题描述:
* N个正数数列,进行如下操作:每一次擦去其中2个数,设a和b,然后在数列中加入一个数ab+1,如此下去直至只剩下一个数。
* 在所有按这种操作方式最后得到的数中,最大的数记为MAX,最小的数记为MIN,则该数列的极差M定义为M=MAX-MIN
* 2. 分析问题:
* 对于给定的数列,如果数列每操作一次就把数列中的值从小到大排列一次,然后按从小到大顺序做运算,则可以得到数列的最大值;
* 如果数列每操作一次就把数列中的值从大到小排列一次,然后按顺序做运算,则可以得到数列的最小值。
* 3. 计算最大值:
* (1)把原始数组赋值给新数组 maxArr
* (2)对数组 maxArr 进行如下循环操作,直至剩余一个值,即为最大值: ①对 maxArr按升序排序;②从 maxArr的第一位开始进行
* ab+1操作,数组第一位为第一操作数,数组最后一位为最后一位操作数, 把运算结果赋值给参与操作的第二个操作数;
* ③删除第一个操作数;④重复第①步。
* 4.计算最小值:与第3步相同,只是从数组(数组已从小到大排完序)最后一位开始进行运算。
*
* @author jun
*/
public class Greedy {
/*
* 贪心算法
*/
public static int greedy(int[] arr) {
// 计算数组最大值
// 创建新数组 maxArr,将原始数组复制给 maxArr,原数组保持不变,因为数组是引用类型,所以不能把 arr赋值给 maxArr,设数列最大值 max
int[] maxArr = Arrays.copyOf(arr, arr.length);
int max = 0;
// 进入循环计算
for (int i = 0; i < (maxArr.length – 1); i++) {
// 对数组 maxArr按升序排序
Arrays.sort(maxArr);
max = maxArr[i];
// 把每次排完序后的值都输出,便于观察过程
System.out.println(“求最大值时第” + (i + 1) + “次排序后数列值变为:”);
System.out.println(Arrays.toString(maxArr) + “\n”);
max = max * maxArr[i + 1] + 1;
// 将数组第二位设值为 max
maxArr[i + 1] = max;
// 将数组第一位设值为无穷小,不再参与运算
maxArr[i] = Integer.MIN_VALUE;
}
// 输出最大值
System.out.println(“最大值 max = ” + max + “\n”);
// 计算数组最小值
// 创建新数组 minArr,把原值数组复制给 minArr,设数列最大值 min
int[] minArr = Arrays.copyOf(arr, arr.length);
int min = 0;
// 进入循环计算
for (int i = (minArr.length – 1); i > 0; i–) {
// 每运算一次,就对数组 minArr按升序做一次排序,然后从大到小计算
Arrays.sort(minArr);
System.out.println(“求最小值时第” + (minArr.length – i) + “次排序后数列值变为:”);
System.out.println(Arrays.toString(minArr) + “\n”);
min = minArr[i];
min = min * minArr[i – 1] + 1;
// 把数组倒数第二位设值为 min
minArr[i – 1] = min;
// 把数组最后一位设值为无穷大,不再参数运算
minArr[i] = Integer.MAX_VALUE;
}
// 输出最小值
System.out.println(“最小值 min = ” + min);
return (max – min);
}
}
以下为测试函数:
package com.work.home_3_1;
import java.util.Arrays;
import java.util.Scanner;
/**
* 测试函数
* @author jun
*/
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(“请输入正整数数列的元素个数 n = “);
int n = sc.nextInt();
sc.close();
// 测试数组
int[] arr = new int[n];
// 给数组赋值
System.out.println(“原始数列值为:”);
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 10);
}
// 输出数组值
System.out.println(Arrays.toString(arr));
// 输出数列的极差
System.out.println(“\n数列arr的极差为:” + Greedy.greedy(arr));
}
}