LeetCode 1066. Campus Bikes II

Posted hankunyan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1066. Campus Bikes II相关的知识,希望对你有一定的参考价值。

Backtracing + Pruning (TLE)

最容易的解法是 backtracing,但是即使加了剪枝,还是会超时。

class Solution 
public:
    int min_dist=INT_MAX;
        
    int assignBikes(vector<vector<int>>& workers, vector<vector<int>>& bikes) 
        vector<bool> bikeUsed(bikes.size(),false);
        dfs(workers,bikes,0,bikeUsed,0);
        return min_dist;
    
    
    // assign a bike to employee i
    void dfs(vector<vector<int>>& workers, vector<vector<int>>& bikes, int i, vector<bool> &bikeUsed, int sum)
        if (i==workers.size())
            min_dist = min(min_dist, sum);
            return;
        
        if (sum>min_dist) return; // pruning
        
        for (int j=0;j<bikes.size();++j)
            if (bikeUsed[j]) continue;
            bikeUsed[j] = true;
            dfs(workers,bikes,i+1,bikeUsed,sum+dist(workers[i],bikes[j]));
            bikeUsed[j] = false;
        
    
    
    int dist(vector<int> worker, vector<int> bike)
        return abs(worker[0]-bike[0])+abs(worker[1]-bike[1]);
    
;

 

Backtracing + Memoization

加一个memo减少递归次数。由于上面的写法的递归函数返回void,要修改为有返回值的写法才能运用memo。

让 dfs 返回值为最小的距离和,然后将 bikeUsed 作为判断标识。由于bike的数量<=10,我们可以用int二进制对这个vector进行压缩作为key。这里只需要 bikeUsed 的原因是,从这个数组我们能得知分配了多少车,而人又是根据序号依次分配的,所以能得出哪些人还没有车。所以 bikeUsed 数组就能唯一确定一个子问题的状态。

class Solution 
public:   
    int assignBikes(vector<vector<int>>& workers, vector<vector<int>>& bikes) 
        vector<bool> bikeUsed(bikes.size(),false);
        unordered_map<int,int> memo; 
        return dfs(workers,bikes,0,bikeUsed,memo);
    
    
    // assign a bike to employee i
    int dfs(vector<vector<int>>& workers, vector<vector<int>>& bikes, int i, vector<bool> &bikeUsed, unordered_map<int,int> &memo)
        if (i==workers.size())  return 0;
        
        int compressed_bikeUsed=compress(bikeUsed);
        if (memo.count(compressed_bikeUsed))
            return memo[compressed_bikeUsed];
        
        int min_dist=INT_MAX;
        for (int j=0;j<bikes.size();++j)
            if (bikeUsed[j]) continue;
            bikeUsed[j] = true;
            min_dist = min(min_dist, dfs(workers,bikes,i+1,bikeUsed,memo) + dist(workers[i],bikes[j]));
            bikeUsed[j] = false;
        
        return memo[compressed_bikeUsed]=min_dist;
    
    
    int dist(vector<int> worker, vector<int> bike)
        return abs(worker[0]-bike[0])+abs(worker[1]-bike[1]);
    
    
    int compress(vector<bool> bikeUsed)
        int res=0;
        for (int i=0;i<bikeUsed.size();++i)
            res <<= 1;
            res |= bikeUsed[i];
        
        return res;
    
;

 

DP

既然可以 Backtracing + Memoization,那么也肯定可以 dp 来做。面试中遇到还是 backtracing 不容易出错。

待补...

 

Reference

https://leetcode.com/problems/campus-bikes-ii/discuss/305218/DFS-+-Pruning-And-DP-Solution

https://leetcode.com/problems/campus-bikes-ii/discuss/320683/Java-7ms-DFS-+-Memorization-Solution-Beats-97

以上是关于LeetCode 1066. Campus Bikes II的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 1057. Campus Bikes

LeetCode 1057. Campus Bikes

使用 OpenGL API 播放 BIK 视频

mysql错误1066

迭代连接集后的 PIG 错误 1066。

错误 #1066 - MySQL 中的表/别名不是唯一的