列表

详情


OR8. 61-递归和动态规划-汉诺塔II

描述

有一个int数组arr其中只含有1、2和3,分别代表所有圆盘目前的状态,1代表左柱,2代表中柱,3代表右柱,arr[i]的值代表第i+1个圆盘的位置。比如,arr=[3,3,2,1],代表第1个圆盘在右柱上、第2个圆盘在右柱上、第3个圆盘在中柱上、第4个圆盘在左柱上。如果arr代表的状态是最优移动轨迹过程中出现的状态,返回arr这种状态是最优移动轨迹中的第几个状态。如果arr代表的状态不是最优移动轨迹过程中出现的状态,则返回-1。

给定一个int数组arr及数组的大小n,含义如题所述,请返回一个int,代表所求的结果。

测试样例:
[3,3]
返回:3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 1ms, 内存消耗: 372KB, 提交时间: 2017-09-04

class Hanoi {
public:

int chkStep(vector<int> arr, int n) 
    {
        int sum = 0,st = 1,by = 2,ta = 3,i = arr.size()-1;
    	for(;i>=0&&arr[i]!=by;i--){
            if(arr[i] == ta){
                sum+=1<<i;
                swap(st,by);
            }else{
                swap(by,ta);
            }
        }
    	return i>=0?-1:sum;
    }
//注意到题中认为标号大的块就是体积更大的块,则从最大的块或最大标号处开始。
//如果最大的块还在start处,则计算子问题,如果放在了target处,则前面的一个子问题已经完成,2^n-1,再加上当前块本身的一次移动,然后再加上子问题的需要步数。
};

C++ 解法, 执行用时: 2ms, 内存消耗: 364KB, 提交时间: 2021-03-22

class Hanoi {
public:
    int chkStep(vector<int> arr, int n) {

 int sum=0,cur=arr.size()-1,start=1,target=3,bypass=2;
        for(;cur>=0&&arr[cur]!=bypass;cur--)
            if(arr[cur]==start)
               swap(bypass,target);
            else
               sum+=1<<cur,swap(bypass,start);
        return cur>=0?-1:sum;
    }
};

C++ 解法, 执行用时: 2ms, 内存消耗: 376KB, 提交时间: 2020-08-17

class Hanoi {  
public:  
    int process(vector<int> &arr,int i,int from,int mid,int to){  
        if(i==-1)  
            return 0;  
        if(arr[i]!=from && arr[i]!=to)  
            return -1;  
        if(arr[i]==from)  
            return process(arr,i-1,from,to,mid);  
        else{  
            int res=process(arr,i-1,mid,from,to);  
            if(res==-1)  
                return -1;  
            return (1<<i)+res;  
        }  
    }  
    int chkStep(vector<int> arr, int n) {  
        // write code here  
        if(arr.empty()||n<=0)  
            return -1;  
        return process(arr,n-1,1,2,3);  
    }  
};  

C++ 解法, 执行用时: 2ms, 内存消耗: 412KB, 提交时间: 2022-04-20

class Hanoi {
public:
    //第i个盘是当前最大的盘,按照最优移动应该被移动到3上去。
    int hanoi(vector<int> arr,int i,int from,int mid,int to){
        if(i==-1) return 0;
        //最大盘不会在中间
        if(arr[i] == mid) return -1;
        //最大盘还在左边,就将左的i-1个移动到中间,,,
        else if(arr[i] == from) return hanoi(arr,i-1,from,to,mid);
        //最大盘在右边
        else{
            int h = hanoi(arr,i-1,mid,from,to);
            if(h==-1) return -1;
            return (1<<i)+h;
        }
    }
    int chkStep(vector<int> arr, int n) {
        if(arr.size()==0||arr.size()!=n) return -1;
        return hanoi(arr, n-1,1,2,3);
    }
};

C++ 解法, 执行用时: 2ms, 内存消耗: 416KB, 提交时间: 2022-02-27

class Hanoi {
public:
    int chkStep(vector<int> arr, int n) {
        // write code here
        if(n==0) return -1;
        int i=n-1,ans=0;
        int left=1,mid=2,right=3,temp=2;
        while(i>=0){
            if(arr[i]!=left&&arr[i]!=right){
                return -1;
            }
            else if(arr[i]==left){
                temp=right;
                right=mid;
            }
            else{
                ans+=1<<i;
                temp=left;
                left=mid;
            }
            i--;
            mid=temp;
        }
        return ans;
    }
};

上一题