zoukankan      html  css  js  c++  java
  • 贪心算法

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

  • 相关阅读:
    HDU 1402 A * B Problem Plus (FFT)
    CodeForces 935E Fafa and Ancient Mathematics (树形DP)
    HDU 5355 Cake (构造 + 暴力)
    HDU 5360 Hiking (贪心)
    Java高阶回调,回调函数的另一种玩法
    关于git 指令
    Retrofit2 完全解析 探索与okhttp之间的关系
    HTTP中GET与POST的区别
    TCP,IP,HTTP,SOCKET区别和联系
    android 实现类似qq未读消息点击循环显示
  • 原文地址:https://www.cnblogs.com/blogtech/p/12294316.html
Copyright © 2011-2022 走看看