zoukankan      html  css  js  c++  java
  • Leetcode 801 使序列递增的最小交换次数

      回溯搜索:

        /**
         * @Author Niuxy
         * @Date 2020/7/12 6:41 下午
         * @Description 回溯法, 暴力搜索
         */
        public int minSwap0(int[] A, int[] B) {
            if (A.length == 0) {
                return 0;
            }
            minSwap(A, B, 0, 0);
            return an;
        }
    
        int an = Integer.MAX_VALUE;
    
        public void minSwap(int[] A, int[] B, int point, int nums) {
            if (point == A.length) {
                if (isIncrease(A) && isIncrease(B)) {
                    an = Math.min(an, nums);
                }
                return;
            }
            change(A, B, point);
            minSwap(A, B, point + 1, nums + 1);
            change(A, B, point);
            minSwap(A, B, point + 1, nums);
        }
    
        private void change(int[] A, int[] B, int point) {
            int temp = A[point];
            A[point] = B[point];
            B[point] = temp;
        }
    
        private boolean isIncrease(int[] nums) {
            if (nums.length == 1) {
                return true;
            }
            for (int i = 1; i < nums.length; i++) {
                if (nums[i] <= nums[i - 1]) {
                    return false;
                }
            }
            return true;
        }

      剪枝分治:

    /**
         * @Author Niuxy
         * @Date 2020/7/12 7:10 下午
         * @Description 回溯算法的回溯点在于,每次交换元素后,该操作会对后续的判断产生影响
         * 题目要求求最小交换次数,也就是说经过有限次数的交换,两个数列最终一定会严格递增
         * 每个元素小于其相邻的后续元素是数列严格递增的充分条件
         * 可以通过不断比较相邻的两个元素来判断数列是否递增
         * 可以通过将可能被交换的元素存储在递归函数入参中,来替代回溯
         * 每个元素只有两种选择,交换与不交换,那么:
         * 1,当 A,B 在该元素上不是严格递增的,必须交换(剪枝)
         * 2,否则有交换与不交换两种可能
         * 遍历每个元素,求它们所有可能选择集合的笛卡尔积
         * 2 情况会导致计算过程中存在重复计算,通过缓存避免
         * 相比于回溯的暴力搜索,通过对元素区分情况 1,2 进行了剪枝,避免了部分无效计算
         * 同时通过缓存避免了部分重复计算
         */
        public int minSwap(int[] A, int[] B, int point, int a, int b, Map<Integer, Integer> cache) {
            if (point == A.length) {
                return 0;
            }
            int key = a * 3 + b * 1733 + point * 17333;
            if (cache.containsKey(key)) {
                return cache.get(key);
            }
            int re = 0;
            if ((A[point] <= a || B[point] <= b) && A[point] != B[point]) {
                re = minSwap(A, B, point + 1, B[point], A[point], cache) + 1;
            } else {
                re = minSwap(A, B, point + 1, A[point], B[point], cache);
                if (B[point] > a && A[point] > b) {
                    re = Math.min(minSwap(A, B, point + 1, B[point], A[point], cache) + 1, re);
                }
            }
            cache.put(key, re);
            return re;
        }
    
        public int minSwap(int[] A, int[] B) {
            if (A.length == 0) {
                return 0;
            }
            return minSwap(A, B, 0, Integer.MIN_VALUE, Integer.MIN_VALUE, new HashMap<Integer, Integer>());
        }

  • 相关阅读:
    ssh免密码登录
    nginx做负载均衡+keepalived(做主备)
    centos之Too many open files问题-修改linux最大文件句柄数
    redis-JedisPoolConfig配置
    Hadoop端口说明
    hadoop 2.5 安装部署
    Java集合框架 10 连问,你有被问过吗?
    Dubbo面试八连问,这些你都能答上来吗?
    面试官:关于Java性能优化,你有什么技巧
    Docker从入门到掉坑(三):容器太多,操作好麻烦
  • 原文地址:https://www.cnblogs.com/niuyourou/p/13290881.html
Copyright © 2011-2022 走看看