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>());
        }

  • 相关阅读:
    JS判断是PC端还是移动端
    js对象转数组
    js获取当前域名、Url、相对路径和参数以及指定参数
    javascript返回上一页的三种写法
    js正则归纳总结
    higtcharts 生成图表个数问题
    js如何处理后台传递过来的Map
    jQuey实现鼠标滑过整行变色
    <display:column>常用属性解释
    <display:table>常用属性解释
  • 原文地址:https://www.cnblogs.com/niuyourou/p/13290881.html
Copyright © 2011-2022 走看看