801. Minimum Swaps To Make Sequences Increasing

首先这道题为什么可以用dp?
后面的状态不会影响前面的,好像有个名词叫non after effect什么的,可能我记错了。
这个还是比较直接的,我们不知道要不要swap, 那索性两种状态都记录一下。
dp可以用来求最小值, 所以比较适合动态规划。
时间复杂度是O(N), 空间复杂度是O(N), 可优化成O(1)的空间。

    public int minSwap(int[] A, int[] B) {
        int[][] dp = new int[A.length][2];
        //dp 状态 dp[i][0] 此行不换之前的最少swap
        //dp[i][1] 此列换的话一共需要的最少swap
        dp[0][0] = 0;
        dp[0][1] = 1;
        for (int i = 1; i < A.length; i++) {
            if (A[i] == B[i]) {
                dp[i][0] = Math.min(dp[i - 1][0], dp[i - 1][1]);
                dp[i][1] = dp[i][0];
            } else {
                if (B[i] <= B[i - 1] || A[i] <= A[i - 1]) { // must swap, 
                    //假设一定有解,所以swap一下肯定可以 
                    dp[i][0] = dp[i - 1][1]; //swap 前面的
                    dp[i][1] = 1 + dp[i - 1][0]; //swap自己 
                } else if (B[i] <= A[i - 1] || A[i] <= B[i - 1]) { // must not swap
                    dp[i][0] = dp[i - 1][0]; // 我不动,前面的也不能动 
                    dp[i][1] = dp[i - 1][1] + 1; //我动,前面的也得动
                } else { // can do either swap or not swap, 咋都行
                    dp[i][0] = Math.min(dp[i - 1][0], dp[i - 1][1]);
                    dp[i][1] = 1 + Math.min(dp[i - 1][0], dp[i - 1][1]);
                }
            }
        }

        return Math.min(dp[A.length - 1][0], dp[A.length - 1][1]);
    }

这道题可以优化的地方是每一个都只跟它上一条记录相关,所以可以用滚动数组来优化空间,变成O(1)的空间。

你可能感兴趣的:(801. Minimum Swaps To Make Sequences Increasing)