首页 > 其他分享 >[LeetCode] Find the Minimum Cost Array Permutation

[LeetCode] Find the Minimum Cost Array Permutation

时间:2024-05-14 23:41:06浏览次数:20  
标签:nums int perm Minimum score answer Find dp Cost

You are given an array nums which is a permutation of [0, 1, 2, ..., n - 1]. The score of any permutation of [0, 1, 2, ..., n - 1] named perm is defined as:

score(perm) = |perm[0] - nums[perm[1]]| + |perm[1] - nums[perm[2]]| + ... + |perm[n - 1] - nums[perm[0]]|

Return the permutation perm which has the minimum possible score. If multiple permutations exist with this score, return the one that is lexicographically smallest among them.

 

Key observations

1. if we fix an answer perm, then rotating it does not change the score, so we might as well start with number 0. The final answer always start with 0.

 

 

When constructing an answer from dp state table, greedily picking a bigger number from right to left to break tie is INCORRECT. Counter example:

nums = [3,4,2,0,1]; perm1 = [0,3,1,2,4]; perm2 = [0,2,4,1,3] score(perm1) = 0 + 1 + 1 + 1 + 1 = 4; score(perm2) = 2 + 1 + 0 + 1 + 0 = 4;  Greedily picking a bigger number returns perm1 but perm2 is lexicographically smaller than perm1.   Given the minimum socre and dp state table, how do you construct the answer then?   Instead of defining dp state as dp[i][j] = min (dp[i ^ (1 << j)][k] + abs(j - nums[k])), where we append number j in the end, we define dp state as: dp[i][j] = min(dp[i | (1 << k)] + abs(j - nums[k])), this way we fixed the prefix of the answer and use dp result to decide which number to pick next.  We can then use another dp array table to track for a current state and last picked number, what is the smallest next number to pick that also yields  a minimum score.   
import java.util.*;

class Solution {
    private int[][] dp, val;
    public int[] findPermutation(int[] a) {
        int n = a.length;
        dp = new int[1 << n][n];
        val = new int[1 << n][n];
        for(int i = 0; i < dp.length; i++) {
            Arrays.fill(dp[i], -1);
            Arrays.fill(val[i], -1);
        }
        compute(a, 1, 0);
        int[] ans = new int[n];
        int prev = 0, idx = 1;
        for(int mask = 1; Integer.bitCount(mask) < n; mask += (1 << prev)) {
            ans[idx] = val[mask][prev];
            idx++;
            prev = val[mask][prev];
        }
        return ans;
    }
    private int compute(int[] a, int currMask, int currV) {
        if(Integer.bitCount(currMask) == a.length) {
            return Math.abs(currV - a[0]);
        }
        if(dp[currMask][currV] < 0) {
            dp[currMask][currV] = Integer.MAX_VALUE;
            for(int nextV = 1; nextV < a.length; nextV++) {
                if((currMask & (1 << nextV)) == 0) {
                    int score = Math.abs(currV - a[nextV]) + compute(a, currMask | (1 << nextV), nextV);
                    if(score < dp[currMask][currV]) {
                        dp[currMask][currV] = score;
                        val[currMask][currV] = nextV;
                    }
                }
            }
        }
        return dp[currMask][currV];
    }
    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] a = new int[]{3,4,2,0,1};
        solution.findPermutation(a);
    }
}

 

 

 

标签:nums,int,perm,Minimum,score,answer,Find,dp,Cost
From: https://www.cnblogs.com/lz87/p/18192451

相关文章

  • 64 - Minimum Path Sum 最小路径和
    64-MinimumPathSum最小路径和问题描述Givenamxngridfilledwithnon-negativenumbers,findapathfromtoplefttobottomright,whichminimizesthesumofallnumbersalongitspath.Note:Youcanonlymoveeitherdownorrightatanypointinti......
  • LeetCode 2956. Find Common Elements Between Two Arrays
    原题链接在这里:https://leetcode.com/problems/find-common-elements-between-two-arrays/description/题目:Youaregiventwo 0-indexed integerarrays nums1 and nums2 ofsizes n and m,respectively.Considercalculatingthefollowingvalues:Thenumberof......
  • Find Products of Elements of Big Array
    FindProductsofElementsofBigArrayA powerfularray foraninteger x istheshortestsortedarrayofpowersoftwothatsumupto x.Forexample,thepowerfularrayfor11is [1,2,8].Thearray big_nums iscreatedbyconcatenatingthe powerful......
  • Windows Basics - Finding Files on Your Computer Back to Tutorial
     everything 推荐用这个工具搜索文件 FindingfilesonyourcomputerInthepreviouslesson,wetalkedabouthowfolderscanhelptokeepyourfilesorganized.However,theremaybetimeswhenyouhavetroublefindingacertainfile.Ifthishappenstoyou......
  • Error: Cannot find module 'C:\Program Files\nodejs\node_modules\npm\bin\no
     #参考:https://stackoverflow.com/questions/69541725/error-cannot-find-module-c-program-files-nodejs-node-modules-npm-bin-node-mod --- #问题描述在一直倒腾重新安装nodejs时报的一个这样的错,记录一下 在执行npm-v时报了如标题的错,见下图 --- #原因......
  • Error: Cannot find module ‘D:\SoftSetupLoaction\nodejs\node_global\node_mod
    Error:Cannotfindmodule‘D:\SoftSetupLoaction\nodejs\node_global\node_modules\npm\bin\npm-cli.js‘  出现原因:重新安装可装了nodejs和npm网上查了很多方法,都建议重装,但是都没有效果(因为我就是重装之后出现的问题)按照错误提示node_global找不到npm-cli.js,个......
  • ERROR: Failed to find vcvars
    ERROR:FailedtofindvcvarsTraceback(mostrecentcalllast):File"F:\code\chromium_git\chromium\src\cef\tools\\make_distrib.py",line954,in<module>combine_libs(platform,src_dir,sandbox_libs,File"F:\code\c......
  • CMake中里的find_package与find_library有什么区别?
    在CMake中,find_package和find_library都是用来找到和链接库的方法,但它们的用法和适用场景略有不同。find_package主要用于寻找具有CMake配置文件的库,这些库通常遵循CMake的规范,提供了用于导入目标、库路径、头文件路径等的配置文件。这使得使用find_package更加简洁,只需指定需......
  • 【cmake】find_package设置查找路径
     1.find_package的作用与实例用来查找第三方依赖包的.cmake文件,并根据.cmake文件生成依赖包的头文件目录和库文件路径等;CMakeLists.txt实例find_package(ProtobufREQUIRED)include_directories(${PROTOBUF_INCLUDE_DIR})add_executable(mainsrc/main.cpp)target......
  • jmap使用报错Doesn't appear to be a HotSpot VM (could not find symbol "gHotSpotVM
    报错场景问题原因服务器上装了jdk,按理来说jmap是自带了的,可以直接使用,根据情况来看是装了jmap但是无法正常使用,推测是版本的问题导致解决方式指定jdk自带的jmap工具1.查看当前java的环境变量echo$JAVA_HOME2.配置jdk自带工具的环境变量exportPATH=$JAVA_HOME/bin:$P......