做小米的笔试题,给出一个整数n,求出它在杨辉三角形中第一次出现的行号。

想了半天,只能暴力法,从第1行开始找,一直找到第n行,若找得到则返回行号,若找不到则返回n+1(因为第n+1行第2列肯定是n)。当然,注意1是在第1行而不是第2行。更好的方法倒是没想到,倒是折腾出了打印杨辉三角形前n行的最优方法。

如果空间不限制的话,就直接定义二维数组a[n][n],初始时a[0][0]=1,通过a[i][j]=a[i-1][j]+a[i-1][j-1]计算即可。这里主要注意的就是边界条件,每一行首尾必须为1,只有夹在首尾中间的n-2个元素才适用于这个公式。

不过后来发现,只是打印的话,完全可以用2个一维数组来表示前一行和当前行。用vector表示的话就是v1和v2,每次通过v1计算出v2,打印完v2之后迭代(用v2给v1赋值)。后来发现除了vector可能重新分配的问题(这里可以vector初始化大小为n来解决),用v2给v1赋值还是很没必要的。

于是想到了可以直接交换指针,v1和v2分配足够大空间后就一直不改变大小,然后int* p1 = &v1[0]; int* p2 = &v2[0];然后每次迭代只需要std::swap(p1,p2)即可。

这里相当于就是用了2片缓冲区(固定大小),其实知道行数上限的话,用2个数组表示也一样。

最后发现,缓冲区一片就够了,这里和copy/copy_backward的原理是类似的,只要从后往前遍历的话就不会导致新元素覆盖了旧元素从而计算出错。

然后更进一步,杨辉三角形每一行是对称的。于是我们只需要取前半部分即可,对于奇数行取(n+1)/2个,对于偶数行取n/2个,按照C/C++中除法取整来看都是(n+1)/2个。

关键是,第2k+1行和第2k+2行的前半部分元素数量相同(比如第3行是1,2,第4行是1,3),而第2k+3行最后一个元素无法直接计算。其实仔细看看就会发现规律,由于对称性,第2k+3行最后一个元素是第2k+2行最后一个元素的2倍。

到这里就可以写代码了,但是写代码的时候直接按这个思路来代码会很丑,因为奇数行最后一个元素的计算方式和前面元素的计算方式不一致。一个优雅的写法是,每当从偶数行跳到奇数行时,元素数量增加,并且初始时在末尾添加一个元素,再批量计算。

比如第4行是1 3,那么第5行初始化后就是1 3 3。然后a[2] = a[1] + a[0]; a[1] = a[1] + a[0];来计算。

// 打印杨辉三角形的前n行
void printPascalTriangle(int n)
{
int maxrow = (n + ) / ;
vector<int> v(maxrow + );
v[] = ; // 哨兵节点
bool bOddRow = true; // 奇数行则为true
int num = ; // 需要计算的元素数量
for (int row = ; row <= n; row++)
{
if (bOddRow)
{
num++;
v[num] = v[num - ];
}
for (int i = num; i > ; i--)
v[i] += v[i - ]; for (int i = ; i <= num; i++) // 正向打印
cout << v[i] << " ";
if (!bOddRow) // 对于偶数行最后一个元素需要再打印一遍
cout << v[num] << " ";
for (int i = num - ; i >= ; i--) // 反向打印
cout << v[i] << " ";
cout << endl;
bOddRow = bOddRow ? false : true; // 行号+1后改变了奇偶性
}
}

O(n)空间复杂度,打印杨辉三角形的前n行的更多相关文章

  1. 算法-利用队列实现逐行打印杨辉三角形的前n行

    分别打印二项式(a+b)^n展开项的系数,在程序中利用了一个队列,在输出上一行系数时,将下一行的系数预先放入队列中.在各行系数间插入0. void YANGVI(int n){ Queue q(n+) ...

  2. ACM解题之快速输出杨辉三角形(前68行)

    题意: 本题要求计算并输出杨辉三角形的前 68 行. Time Limit:1000MS Memory Limit:65536K 解题: 为了能在规定时间准确输出杨辉三角形的前68行,这里我用了精准的 ...

  3. 17.从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行。请采用循环控制语句来实现。 (三角形腰上的数为1,其他位置的数为其上一行相邻两个数之和。) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1

    17.从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行.请采用循环控制语句来实现. (三角形腰上的数为1,其他位置的数为其上一行相邻两个数之和.) 1 1 1 1 ...

  4. 从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行。请采用循环控制语句来实现。

    Scanner sc=new Scanner(System.in); System.out.println("请输入一个正整数:"); int ss=sc.nextInt(); i ...

  5. grep命令打印前N行

    想打印前5行,用head即可:grep xxx |head -n 5

  6. linux利用grep查看打印匹配的下几行或前后几行的命令

    转自:http://www.itokit.com/2013/0308/74883.html linux系统中,利用grep打印匹配的上下几行   如果在只是想匹配模式的上下几行,grep可以实现.   ...

  7. spark dataframe操作集锦(提取前几行,合并,入库等)

    https://blog.csdn.net/sparkexpert/article/details/51042970 spark dataframe派生于RDD类,但是提供了非常强大的数据操作功能.当 ...

  8. linux grep打印匹配的上下几行

    $grep -5 'parttern' inputfile //打印匹配行的前后5行 $grep -C 5 'parttern' inputfile //打印匹配行的前后5行 $grep -A 5 ' ...

  9. 1233: 输出杨辉三角前n行(Java)

    WUSTOJ 1233: 输出杨辉三角前n行 题目 原题链接 Description 输出杨辉三角前n行. Input 输入一个数n(n <= 9) Output 输出杨辉三角前n行.(注意行末 ...

随机推荐

  1. ECC算法整理纪要

    初始ECC算法 1.用户A 密钥生成 (1):用随机数发生器产生随机数k∈[1,n-1]: (2):计算椭圆曲线点PA=[k]G,为公钥,k为用户A私钥: 2. 用户B加密算法及流程 设需要发送的消息 ...

  2. python关于时间的计算,time模块

    import time, datetime # time.time 返回当前时间的时间戳(1970纪元后经过的浮点秒数)(格林尼治时间). # 1分钟60秒,1小时3600秒,1天86400秒. pr ...

  3. doom启示录

    半个小时之后,doom的最后一个字节抵达威斯康星大学,瞬间,上万名玩家涌向那台服务器,淹没了她,威斯康星大学的服务器瘫痪了,大卫的服务器崩溃了. “天哪”大卫在电话里结结巴巴地对杰伊说:“我还从没见过 ...

  4. NodeJS 难点(网络,文件)的 核心 stream 四: writable

    什么是可写流 白板 可写流是对数据流向设备的抽象,用来 消费  上游流过来的数据 通过可写流程序可以把数据写入设备, 常见的是 本地磁盘文件或者 TCP.HTTP 等网络响应. 看一个之前用过的例子 ...

  5. Linux:at命令详解

    at命令 at命令为单一工作调度命令.at命令非常简单,但是在指定时间上却非常强大 语法 at [选项] time at > 执行的命令 ctrl+d 选项 -m :当指定的任务被完成之后,将给 ...

  6. springboot跨域请求

      首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源 SpringBoot | 番外:使用小技巧合集 2018/09/17 | 分类: 基础技术 | 0 条评论 | 标 ...

  7. A+B for Input-Output Practice (VIII)

    A+B for Input-Output Practice (VIII) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3276 ...

  8. NVIDIA GeForce GTX 960 设备是不可移动的,无法弹出

    系统环境 系统:win7_x64; matlab版本:matlab2017b试用版: GPU:NVIDIA GeForce GTX 960: 问题描述: 第一次使用深度学习实现代码,运行的是matla ...

  9. HTML第三课——css盒子

    请关注公众号:自动化测试实战 css常用属性 width 宽 height 高 color 字体颜色 border 边框 background 背景 lesson3.html <!DOCTYPE ...

  10. 来自官方的一些dbt 最佳实践

    限制对原始数据的依赖性 您的项目将取决于存储在数据库中的原始数据.我们建议制作所谓的“基本模型”,以最大限度地减少对原始数据表的依赖性.在此约定中,基本模型可以具有以下职责: 仅选择与当前分析相关的字 ...