做小米的笔试题,给出一个整数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. UVALive 4168

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA08AAABMCAIAAAA6IBt+AAAgAElEQVR4nO1dybXjOg7tWJSK65yKxL

  2. SpingBoot三——基础架构

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:https://www.cnblogs.com/by-dream/p/10492073.html 继续上一节,为了更好的开发,现将 ...

  3. <转>字符编码

    转: 字符编码笔记:ASCII,Unicode和UTF-8   作者: 阮一峰 日期: 2007年10月28日 今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. ...

  4. 中国教授在BlackHat现场演示破解SIM卡AES-128加密

    使用一个PC和示波器克隆3G/4G SIM卡,破解过程只需十分钟.上海交大教授郁昱现场展示了如何成功复制SIM卡,以及一张克隆卡如何变更了支付宝的密码并潜在盗取账户资金. 破解SIM卡加密 今年二月, ...

  5. 如何把dos命令窗口里的字符复制下来?

    简单一点的操作就是右键点“标记”选中需要复制的内容点左上角的小图标 编辑 复制

  6. Foundation--结构体

    一,NSRange typedef struct _NSRange { NSUInteger location; NSUInteger length; }NSRange; 这个结构体用来表示事物的一个 ...

  7. 大龄码农那些事——也谈996.ICU

    1.背景 近期Github突然有一个开源项目火了,叫“996.icu”,开源地址:https://github.com/996icu/996.ICU ,目前star的人数截止我写这篇博文时已经高达17 ...

  8. 【linux】如何退出shell终端

    退出shell终端: exit + 回车即可 清除当前屏幕信息 clear 不过clear只是将之前的命令向上隐藏啦...

  9. caffe安装编译问题-ImportError: No module named caffe

    问题描述 ~/Downloads/caffe$ python Python (default, Dec , ::) [GCC ] on linux2 Type "help", &q ...

  10. Mac OS 基于 VirtualEnv 的安装 tensorflow 1.3.0

    如果不行的话,就用conda装吧 https://www.jianshu.com/p/d54546ab315e 推荐使用 virtualenv 创建一个隔离的容器, 来安装 TensorFlow. 这 ...