贪心算法 - 删除问题

(1)问题描述:给定 n 位正整数 a,去掉其中任意 k <= n 个数字后,剩下的数字按原来次序排列组成一个正整数。对于给定的 n 为正整数 a 和正整数 k 设计一个算法找出剩下数字组成的新数最小的删数方案;

(2)算法设计:对于给定的正整数 a,计算删去 k 个数字后得到的最小数;

(3)算法思想:删掉要删的,留下要留的;在给定的数 a,对于其每一位上的数,采用贪心算法,局部最优的方式,留下最小的数位;前提:在删除过程中,急要保证该位上的数字最小,又要确保删除数时够删的原则;

(4)核心代码:

 

public class DeleteData {

    /**
     * 给定的正整数
     */
    private static Integer num;

    /**
     * 存放数据数组
     */
    private static Integer[] data;

    /**
     * 删除总数
     */
    private static Integer total;

    /**
     * 删除标识
     */
    private static Boolean[] deleteFlag;

    /**
     * 初始化数据
     */
    private static void initData() {
        Integer index = 0;
        Scanner input = new Scanner(System.in);

        System.out.println("请输入给定的正整数:");
        String numStr = input.nextLine();
        num = Integer.valueOf(numStr);

        System.out.println("请输入删除正整数的个数:");
        total = input.nextInt();
        data = new Integer[numStr.length()];
        deleteFlag = new Boolean[numStr.length()];

        // 拆分 num 元素,存放到 data 数组【178543  -->  data = {3, 4, 5, 8, 7, 1}】
        while(num != 0) {
            data[index] = num % 10;
            num = num / 10;
            deleteFlag[index] = false;
            index++;
        }
        // data 数组逆置
        for (int i = 0, j = data.length - 1; i < j; i++, j--) {
            Integer temp = data[i];
            data[i] = data[j];
            data[j] = temp;
        }
    }

    /**
     * 删除
     */
    private static void deleteData() {
        int find = 0;       // 初始从下标为 0 开始找
        while(total != 0) {
            int min = 10;
            int index = -1;
            // data.length - i 表示在下标为 i 后面剩余的数字,大于等于要查找的数字个数 total,确保够删
            for (int i = find; i < data.length && data.length - i >= total; i++) {
                if (data[i] < min) {
                    min = data[i];
                    index = i;
                }
            }
            if (index >= 0) {
                deleteFlag[index] = true;   // 留下要留的数字
            }
            find = index + 1;           // 下次寻找直接从 index 的下一位开始,因为当前位已经是最小的,不必重复查找
            total--;
        }
    }

    /**
     * 输出
     */
    private static void print() {
        System.out.println("删除后最小值为:");
        for (int i = 0; i < deleteFlag.length; i++) {
            if (deleteFlag[i]) {
                System.out.print(data[i]);
            }
        }
    }

    public static void main(String[] args) {
        // 初始化数据
        initData();

        // 删除
        deleteData();

        // 输出
        print();
    }

}

 

(5)输入输出:

请输入给定的正整数:
178543
请输入删除正整数的个数:
2
删除后最小值为:
13

(6)总结:删数问题极大的反应出贪心算法的思想,每次循环删数时,都寻找局部最优解,最后删除完之后,留下的就是最优解;

 

posted @ 2020-02-11 11:31  菜鸟的奋斗之路  阅读(1168)  评论(0编辑  收藏  举报