算法:从序列里找到最长的以1降序的子序列

来源:互联网 发布:警告本网站域名在美国 编辑:程序博客网 时间:2024/06/05 19:06

前言:某公司的现场coding题,结果在C++下面纠结超时了,挂掉。

实际上很简单的一道题,回来用C实现了一遍,还是用最原始的最有把握…

——————————————————————————

题目:在一串序列中找到最长的一段以1降序排列的子序列

例如输入:125438765412202152 输出:87654

以下是C代码,gcc编译。

声明:没有考虑出现等长的多个序列的情况,这不涉及到算法实质懒得实现了;另外END标记值得斟酌。

/** * Find the longest Sequence decreased by 1 * imput:1,0,3,4,8,7,6,5,4,2,1,0,2,3,2,1,0 * output:8,7,6,5,4 * 14.6.15 */#include "stdio.h"#include "malloc.h"#define END 99999   /* mark the END of an array *//** * input: an array and its length, the result array */ void longestSeq(int *a, int n, int *ret){int *tmp;int ltmp, lret;int i, j, k;ltmp = 1; /* length of tmp */lret = 0; /* length of ret */tmp = malloc( n * sizeof(int) + 1);for ( i = 0, j = 0; i < n; ++i ) {if ( a[i] - a[i+1] == 1) {/* copy to tmp */tmp[j] = a[i];tmp[j+1] = a[i+1];tmp[j+2] = END;++j;++ltmp;} else {if ( lret < ltmp ) {/* copy tmp to ret */lret = 0;k = 0;while ( tmp[k] != END ) {ret[k] = tmp[k];++k;++lret;}ret[k] = END;} /* clear tmp */j = 0;ltmp = 1;}}}int main(){int a[] = {1,0,3,4,8,7,6,5,4,2,1,0,2,3,2,1,0,-1,-2,-3,9,8,7,6,5,4};int n = sizeof(a)/sizeof(int); /* the length of a[] */int res[n+1]; /* result array */int i = 0;longestSeq(a, n, res);/* print res */while ( res[i] != END ) {printf("%d ", res[i]);++i;}return 0;}

Review:算法倒是不难,不过有不少细节需要注意

1. 思路要清晰


如上图,longestSeq函数里面主要有三个数组被操作。

流程:遍历一趟输入a,只要是符合降序1的子序列都存到临时tmp中,然后在断序时判断tmp和ret的长度,ret永远保存最长的tmp。

2. tmp = malloc( n * sizeof(int) + 1); 这一句,给tmp分配了(n+1)个空间,因为末尾加了END标记,防止溢出啊。

3. #define END 99999 暂时用这种原始的办法作为数组末尾标记,不知各位有何建议。

4. 容易出错的地方,也是老面孔了,对数组游标的控制,往往可能不是多了1就是少了1,细心演算一下即可。

0 0
原创粉丝点击