算法基础部分-贪心算法

//贪心算法
public class Tanxing {

    //会议最多举行多少场问题
    public static class Program {
        public int start;
        public int end;
    }

    public static class ProgramComparator implements Comparator<Program> {

        @Override
        public int compare(Program o1, Program o2) {
            return o1.end - o2.end;
        }
    }

    public static int bestArrange(Program[] programs, int timePoint) {
        //首先根据会议结束时间来升序排序
        Arrays.sort(programs, new ProgramComparator());
        int result = 0;
        //从左往右依次遍历所有的会议
        for (int i = 0; i < programs.length; i++) {
            //如果会议开始时间大于当前时间则可以加入
            if (timePoint <= programs[i].start) {
//                可加入会议数加一
                result++;
//                当前时间变成当前会议结束时间
                timePoint = programs[i].end;
            }
        }
        return result;
    }

    //字符串组成最小字典序问题
    public static class MyComparator implements Comparator<String> {
        @Override
        public int compare(String a, String b) {
            return (a + b).compareTo(b + a);
        }
    }

    public static String lowestString(String[] strs) {
        if (strs == null || strs.length == 0) {
            return "";
        }
        Arrays.sort(strs, new MyComparator());
        String res = "";
        for (int i = 0; i < strs.length; i++) {
            res += strs[i];
        }
        return res;
    }

    //最少钱最大利润
    public static int lessMoney(int[] arr) {
        PriorityQueue<Integer> pQ = new PriorityQueue<>();
        for (int i = 0; i < arr.length; i++) {
            pQ.add(arr[i]);
        }
        int sum = 0;
        int cur = 0;
        while (pQ.size() > 1) {
            cur = pQ.poll() + pQ.poll();
            sum += cur;
            pQ.add(cur);
        }
        return sum;
    }

    public static class MinComparator implements Comparator<Linkedlist.Node> {

        @Override
        public int compare(Linkedlist.Node o1, Linkedlist.Node o2) {
            return o1.C - o2.C;
        }
    }

    public static class MaxComparator implements Comparator<Linkedlist.Node> {

        @Override
        public int compare(Linkedlist.Node o1, Linkedlist.Node o2) {
            return o2.P - o1.P;
        }
    }

    public static int findMaximizedCaptital(int k, int w, int[] Prpfits, int[] Capital) {
        PriorityQueue<Linkedlist.Node> minCostQ = new PriorityQueue<Linkedlist.Node>(new MinComparator());
        PriorityQueue<Linkedlist.Node> maxProfiyQ = new PriorityQueue<Linkedlist.Node>(new MaxComparator());
        //所有的项目扔到被锁池中,花费组织的小根堆
        for (int i = 0; i < Prpfits.length; i++) {
            minCostQ.add(new Linkedlist.Node(Prpfits[i], Capital[i]));
        }
        //进行k轮
        for (int i = 0; i < 5; i++) {
            //能力所及的项目全部都解锁
            while (!minCostQ.isEmpty() && minCostQ.peek().C <= w) {
                maxProfiyQ.add(minCostQ.poll());
            }
            if (maxProfiyQ.isEmpty()) {
                return w;
            }
            w += maxProfiyQ.poll().P;
        }
        return w;
    }

    //动态获取中位数
    public static void getzhoweishup(int[] arr) {
        PriorityQueue<Integer> biggestQ = new PriorityQueue<Integer>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });//大根堆
        PriorityQueue<Integer> smartgestQ = new PriorityQueue<Integer>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });//小根堆
        biggestQ.add(arr[0]);//首先第一个数加入大根堆
        for (int i = 1; i < arr.length; i++) {
            //每次加入堆的数之前先跟大根堆的堆顶进行比较 如果大于堆顶就加入到小根堆中,如果小于堆顶就加入到大根堆中 ,如果大根堆或者小根堆里面的元素个数比对方大2个那么就把堆顶给对方
            if (arr[i] > biggestQ.peek()) {
                smartgestQ.add(arr[i]);
            } else {
                biggestQ.add(arr[i]);
            }
            if (biggestQ.size() - smartgestQ.size() == 2) {
                smartgestQ.add(biggestQ.poll());
            } else if (smartgestQ.size() - biggestQ.size() == 2) {
                biggestQ.add(smartgestQ.poll());
            }
            //此时数组中的数都在大根堆和小根堆里面了 然后比较大根堆和小根堆的size 如果相等就栈顶相加除以二 如果不相等就弹出size大的那一个的栈顶
            if (biggestQ.size() > smartgestQ.size()) {
                System.out.println("中位数为:" + biggestQ.peek());
            } else if (biggestQ.size() < smartgestQ.size()) {
                System.out.println("中位数为:" + smartgestQ.peek());
            }
            System.out.println("中位数为:" + ((biggestQ.peek() + smartgestQ.peek()) >> 1));

        }


    }

    //n皇后问题
    public static int num1(int n) {
        if (n < 1) {
            return 0;
        }
        int[] record = new int[n]; //record[i]->i行的皇后,放在了第几列
        return process1(0, record, n);
    }

    private static int process1(int i, int[] record, int n) {
        if (i == n) {//终止行
            return 1;
        }
        int res = 0;
        for (int j = 0; j < n; j++) {
            //record[i]表示第i行的皇后在第几列
            //当前i行的皇后,放在j列,会不会和之前(0...i-1)的皇后,共行共列或者共斜线,
            //如果是,认为无效
            //如果不是,认为有效
            if (isValid(record, i, j)) {
                record[i] = j;
                res += process1(i + 1, record, n);
            }
        }
        return res;
    }

    private static boolean isValid(int[] record, int i, int j) {
        for (int k = 0; k < i; k++) {//之前的某个k行的皇后
            if (j == record[k] || Math.abs(record[k] - j) == Math.abs(i - k)) {
                return false;
            }
        }
        return true;
    }


    //请不要超过32皇后问题
    public static int num2(int n) {
        if (n < 1 | n > 32) {
            return 0;
        }
        //例如你是9皇后 那么1左移9位然后-1 就变成了 1 1111 1111  limit不变的
        int limit = n == 32 ? -1 : (1 << n) - 1;
        return process2(limit, 0, 0, 0);
    }

    // limit 划定了问题的规模->固定
// colLim列的限制,1的位置不能放皇后,0的位置可以
// leftDiaLim 左斜线的限制,1的位置不能放皇后,0的位置可以
// rightDiaLim 右斜线的限制,1的位置不能放皇后,0的位置可以
    public static int process2(
            int limit,
            int colLim,
            int leftDialim,
            int rightDiaLim) {
        //什么时候列的限制变成了1 1111 1111 那么就说明填满了 就说明这个路线可行 返回1
        if (colLim == limit) { // base case
            return 1;
        }
        //所有候选皇后的位置,都在pos上
        //(colLim | leftDiaLim | rightDialim)  总限制
        //~(colLim | leftDiaLim | rightDialim)   右侧是有效的每个1是可以尝试放皇后的位置

        //例如列限制是0001 那么左侧限制就是0010  右侧限制就是 0000  然后把三个或起来就变成了0011 然后取反就变成了1100  然后与上limit 就变成了 皇后可以填入的地方
        int pos = limit & (~(colLim | leftDialim | rightDiaLim));
        int mostRightOne = 0;
        int res = 0;
        while (pos != 0) {
            //取出当前的最右边的可以填入皇后的点 然后填入皇后
            mostRightOne = pos & (~pos + 1);
            //pos当递归返回的时候就尝试下一条路线
            pos = pos - mostRightOne;
            res += process2(limit,
                    // 新的列限制
                    colLim | mostRightOne,
                    // 左斜线限制 每次向下递归的时候要左移
                    (leftDialim | mostRightOne) << 1,
                    // 右斜线限制 每次向下递归的时候要右移
                    (rightDiaLim | mostRightOne) >>> 1);
        }
        return res;
    }


    //暴力递归 汉罗塔问题


    public static void process(int N, String, String, String) {
        if (N == 1) {
            System.out.println("Move " + N + " from " ++ " to " +);
        } else {
            process(N - 1,,,);//第一步:把1到n-1从from移动到help组上去
            System.out.println("Move " + N + " from " ++ " to " +);
            process(N - 1,,,);//第三步:把1到n-1从help上移动到to上去
        }
    }


    public static void main(String[] args) {
//        process(3,"左边","中间","右边");
        int i = num2(9);
//        System.out.println(i);
//        Program p1 = new Program();
//        Program p2 = new Program();
//        Program p3 = new Program();
//        Program p4 = new Program();
//        Program p5 = new Program();
//        Program p6 = new Program();
//        p1.start =7;
//        p1.end =9;
//        p2.start =6;
//        p2.end = 8;
//        p3.start =9;
//        p3.end =12;
//        p4.start =15;
//        p4.end =16;
//        p5.start =13;
//        p5.end =15;
//        p6.start =14;
//        p6.end =17;
//        Program[] programs = {p1,p2,p3,p4,p5,p6};
//        bestArrange(programs,6);
//        String[] strs = {"ab","acd","abc","cda"};
//        lowestString(strs);
//        int[] prpfits = {2,4,7,9,6,3};
//         getzhoweishup(prpfits);
//        System.out.println((4+7)>>1);
//        System.out.println(getzhoweishup);
//        int[] capital = {1,2,2,5,3};
//        int w = 1;
//        int k = 4;
//        int maximizedCaptital = findMaximizedCaptital(k, w, prpfits, capital);
//        System.out.println(maximizedCaptital);
    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值