为了账号安全,请及时绑定邮箱和手机立即绑定

剑指Offer-矩形覆盖

标签:
Java 算法

最近一直在复习一些算法及数据结构方面的东西,就找了一个适合找工作笔试的题目,在剑指Offer上刷了几道题目,发现对复习知识点还是很有用的,做到重建二叉树这块。递归传值出了点问题,debug半小时才找出错误,所有还是写篇博客记录一下。也推荐要找工作的伙伴去剑指Offer刷题。

       

题目描述

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

一看这个题目可以发现,用2*1的小矩阵去横着或者竖着覆盖大矩形,可以分为两种情况:

 1. 竖着放:







可以看出2个2*1的矩阵就是一个组合,很容易发现递归关系式,就是 target = recusion(target - 2),第n项和第n-1项是不可分开的;

2. 横着放:











这一看就跟清楚了,target = recusion(target - 1); 具有最有子结构的特点。

如下代码递归式:

    public int RectCover(int target) {
           
        if(target < 3 && target > 0){
           
            return target;
     
        }else if(target >= 3){   
          
              return RectCover(target - 1) + RectCover(target - 2);
        }
          
        return 0;
        
    }

https://img1.sycdn.imooc.com//5b8a9b50000138cb04400165.jpg


可以看到耗时还是挺慢的,其实递归在数据很大的情况下,很容易导致栈溢出。不仅执行时间慢,而且还会计算重复的步骤,下面是一个优化的版本:

记忆化的DP: 避免了递归重复计算的问题,但是增加了空间复杂度

	    static  int[] arrs = new int[1000];
	    public static int RectCover(int target) {
	        
            if(target <= 0){
                return 0;
            }
            
	    	if(arrs[target] != 0) {
	    		return arrs[target];
	    	}
	    	
	    	if(target == 1 || target == 2) {
	    		arrs[target] = target;
	    	}else {
	    		arrs[target] = RectCover(target-1)+RectCover(target-2);	    		
	    	}
	    	
	    	return arrs[target];
	    }

时间快了不少。


https://img1.sycdn.imooc.com//5b8a9ddb00010b0d03760161.jpg


这个递归其实跟斐波拉切数列是一样的,我们可以用3个整形变量来存放递归重复算的结果,如下:

    public static int RectCover(int target) {
        if(target < 3 && target > 0){
            return target;
        }else{
            int first = 1;
            int second = 2;
            int result = 0;
            for(int i = 3 ; i <= target ; i ++){
                result = first + second;
                first = second;
                second = result;
            }
            return result;
        }
    }

https://img1.sycdn.imooc.com//5b8a9f880001771602440171.jpg




点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
7796
获赞与收藏
665

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消