杨辉三角的变形

题目详情

         1

      1  1  1

   1  2  3  2  1

1  3  6  7  6  3  1

以上三角形的数阵,第一行只有一个数1, 以下每行的每个数,是恰好是它上面的数,左上的数和右上数等3个数之和(如果不存在某个数,认为该数就是0)。

求第n行第一个偶数出现的位置。如果没有偶数,则输出-1。例如输入3,则输出2,输入4则输出3。

输入n(n <= 1000000000)

函数头部:

C/C++:

    int run(int n);

java:

public solution {

    public static int run(int n);

}


首先看完这道题目的时候、给我的第一感觉就是将这个经过变形的杨辉三角存入二维数组或通过递归遍历、然后再遍历最后一行第一个出现的偶数、

在这里通过简单的分析、

1.前两行很直观的就可以看出没有偶数、

2.第一行只有一个数、每一行比前一行多两个数、那么第x行便有2x-1个数、

3.这个变形的杨辉三角是对称的、并且中间的数是奇数、

4.而题目介绍到它的规律是:第一行只有一个数1,以下每行的每个数,是恰好是它上面的数,左上的数和右上数等3个数之和(如果不存在某个数,认为该数就是0)。


分析到这里、我就想若是存在二维数组里面、就应该是下面这个样子、

 0 0 0 1 0 0 0
 0 0 1 1 1 0 0
 0 1 2 3 2 1 0
 1 3 6 7 6 3 1

 …

于是乎、最初开始想的算法并提交到pongo庞果网英雄会的代码如下、


public class Test 
{ 
   public static  int run(int x)
    {
        if(x>2){
            int row = 2*x-1;
            int[][] t = new int[x][row];
            
            for(int j=0;j<x;j++){//遍历行赋值
                for(int i=0;i<row;i++){//遍历列赋值
                    
                    if(j==0){//给第0行赋值
                        if(i==x-1){
                            t[j][i] = 1;
                        }else{
                            t[j][i] = 0;
                        }
                    }else{
                        
                        if(i == 0){//第一列
                            t[j][i] = t[j-1][i] + t[j-1][i+1];
                        }else if (i == row-1){//最后一列
                            t[j][i] = t[j-1][i-1] + t[j-1][i];
                        }else{
                            t[j][i] = t[j-1][i-1] + t[j-1][i] + t[j-1][i+1];
                        }
                        
                    }
                    //--------
                    
                }
            }
            
            for(int i = 0;i<row;i++){//遍历出第一个出现的偶数
                if(t[x-1][i]%2 == 0){
                    return i+1;
                }
            }
        } 
         return -1;
    }
    //start 提示:自动阅卷起始唯一标识,请勿删除或增加。 
    public static void main(String args[]) 
    { 
       System.out.println(run(0));
    } 
    //end //提示:自动阅卷结束唯一标识,请勿删除或增加。
}        

提交后、发现报Exception in thread "main" java.lang.OutOfMemoryError: Java heap space异常、竟然内存溢出、偶了个去、思路是对的啊、怎么会错了呢、然后瞬间想到了什么、好像有个上限、对、就是“输入n(n <= 1000000000)”、那个坑啊、有这么个上限、不错才怪、这种思路是对的、但是用错了地方、题目要求是求第x行第一个偶数出现的位置、那就得换种思维模式对待了、


于是为了更好的找到它的规律、便多写了几行来进行分析、



经过分析得出的结论如下:

1.前两行没有偶数可直接返回-1、

2.从第三行开始、奇数行第一个偶数出现的位置为2、

3.从第四行开始、偶数行第一个偶数出现的位置最少在3以上才出现、

4.结合上面第一次做的分析得出每行都是对称的、第x行x列为奇数、 并且每行的每个数,是恰好是它上面的数,左上的数和右上数等3个数之和、


经过最后分析并总结、返回偶数位置的算法代码如下、

	 public static int run(int x){
		 
		 if(x<=2){//前两行直接返回-1
			 return -1;
		 }else if(x%2 == 1){//奇数行第一个出现偶数为2
			 return 2;
		 }
	 return x / 2 % 2 + 3;
	 }

从某种意义上来讲、第一中算法思路并没有错、它是通过最直接的遍历方法来查找、只是对待存在数的无穷大遍历问题、导致内存溢出、而针对于第二种方法、完全是通过凭感觉去找规律、然后总结得出、虽然第二种算法看起来非常简洁并完美的完成了题目的要求、但不管是第一种错误的思路、还是第二种、它们的关键在于、都给予了我一种去思考的过程、

posted @ 2013-11-08 16:03  Jenly  阅读(703)  评论(0编辑  收藏  举报