笔试算法题(26):顺时针打印矩阵 & 求数组中数对差的最大值
出题: 输入一个数字矩阵,要求从外向里顺时针打印每一个数字;
分析:
- 从外向里打印矩阵有多重方法实现,但最重要的是构建合适的状态机,这样才能控制多重不同的操作;
- 注意有四种打印模式(左右,上下,右左,下上),所以需要一个index变量控制每次循环时执行的打印模式;
- 注意水平打印和垂直打印分别需要两个变量控制打印元素,并且两组变量中的两个端点都是相互靠近的(hs和he,vs和he),每执行一种打印模式之前,需要更新当前打印模式中打印方向的其实坐标,因为它已经在上一种打印模式中打印过;
- 每一种打印模式执行之前需要检测hs>he或者vs>ve,如果成立则打印结束;
- 其他方法:递归法:每次都打印矩阵第一行,然后将剩余的元素逆时针旋转90度创建一个矩阵;贪吃蛇法:创建一个bool矩阵表示元素是否被打印,然后创建一个类似index的控制打印模式的变量,遇到false的元素就转到下一个打印模式;
解题:
/**
* 设置四个变量,两两一组分别表示水平和垂直方向的打印的起始点
* index表示四种打印方式中的一种(左右,上下,右左,下上)
* 当两两一组的变量中hs>he或者vs>ve的时候结束打印
* 注意每一种打印模式开始之前,需要更新起始点的坐标,因为
* 它已经在上一个打印模式中打印过
* */
void clockwisePrintMatrix(int *array, int x, int y) {
int hs=-, he=x-;
int vs=, ve=y-;
int index=; while(true) {
printf("hs=%d, he=%d, vs=%d, ve=%d\n",hs,he,vs,ve);
index%=;
if(index==) {
/**
* 左右打印模式:
*
* */
hs++;
if(hs>he) break;
for(int i=hs;i<=he;i++)
printf("%d, ",array[vs*x + i]);
printf("\n");
} else if(index==) {
/**
* 上下打印模式:
*
* */
vs++;
if(vs>ve) break;
for(int i=vs;i<=ve;i++)
printf("%d, ",array[i*y + he]);
printf("\n");
} else if(index==) {
/**
* 右左打印模式:
*
* */
he--;
if(hs>he) break;
for(int i=he;i>=hs;i--)
printf("%d, ",array[ve*x + i]);
printf("\n");
} else if(index==) {
/**
* 下上打印模式:
*
* */
ve--;
if(vs>ve) break;
for(int i=ve;i>=vs;i--)
printf("%d, ",array[i*y + hs]);
printf("\n");
}
index++;
}
} int main() {
int matrix[]={,,,,,,,,,,,,,,,,,,,,,,,,};
clockwisePrintMatrix(matrix, , );
return ;
}
出题:一个数组中,某一个数字减去它右边数字得到一个数对差,求所有数对差中的最大值;
分析:
- 数对差的解法可转换成求最大子数组和,或者转换成DP问题;
- 解法1:构建子数组最大和值
定义数
组:array[i]-array[i+1];array[i+1]-array[i+2];……;array[j-1]-array[j];所以
array[i]-array[j]的差就是前面所有相邻元素差的和,所以将原始数组转换成相邻元素的差组成的数组,而求原数组元素差的最大值转换成新数
组的子数组元素的最大和; - 解法2:动态规划解法:diff[i]存储array[i]与其左边数组最大元素的差值,得到diff[i]之后求diff[i+1],则需要知道 array[i+1]左边数组的最大元素,而有两种可能,计算diff[i]的时候得到的最大值,或者就是array[i]。所以只需一遍扫描就可以;
解题:
int MaxDif(int *array, int length) {
/**
* 定义局部stack数组存储相邻元素差值
* 循环获取相邻元素差值
* */
int difarray[length-];
for(int i=;i<length-;i++) {
difarray[i]=array[i]-array[i+];
printf("\n%d",difarray[i]);
}
/**
* sum记录最大和值
* tempsum记录当前元素的和值
* 如果元素为+++++++,则从开始相加到最后
* 如果元素为-------,则sum保持为0
* 如果元素为++++---,则sum保持为前半正数
* 如果元素为----+++,则sum保持为后半正数
* 还有其他满足条件的情况
* */
int tempsum=, sum=;
for(int i=;i<length-;i++) {
tempsum+=difarray[i];
if(tempsum<)
tempsum=;
else if(tempsum>sum)
sum=tempsum;
}
return sum;
}
int MaxDifDP(int *array, int length) {
/**
* difarray[i]用于存储array[i]左边的最大元素
* 与array[i]的差值,
* difarray[i+1]同理,但根据DP原理,左边的最大
* 元素可能是array[i]找到的最大元素,可能是
* array[i]本身,所以一遍扫描,DP复用
* */
int difarray[length-];
int max=array[];
for(int i=;i<length-;i++) {
if(array[i]>max)
max=array[i];
difarray[i]=max-array[i+];
}
int difmax=difarray[];
for(int i=;i<length-;i++) {
if(difarray[i]>difmax)
difmax=difarray[i];
}
return difmax;
}
int main() {
int array[]={,,,,-,,,};
printf("\nthe max diff is: %d",MaxDif(array,));
printf("\nthe max diff is: %d",MaxDifDP(array,));
return ;
}
笔试算法题(26):顺时针打印矩阵 & 求数组中数对差的最大值的更多相关文章
- php笔试算法题:顺时针打印矩阵坐标-蛇形算法
这几天参加面试,本来笔试比较简单,但是在面试的时候,技术面试官说让我现场写一个算法,顺时针打印矩阵的坐标,如图所示 顺序为,0,1,2,3,4,9,14,19,24,23,22,21,20,15,10 ...
- 《剑指offer》第二十九题(顺时针打印矩阵)
// 面试题29:顺时针打印矩阵 // 题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. #include <iostream> void PrintMatrixInC ...
- 《github一天一道算法题》:分治法求数组最大连续子序列和
看书.思考.写代码. /*************************************** * copyright@hustyangju * blog: http://blog.csdn. ...
- 笔试算法题(40):后缀数组 & 后缀树(Suffix Array & Suffix Tree)
议题:后缀数组(Suffix Array) 分析: 后缀树和后缀数组都是处理字符串的有效工具,前者较为常见,但后者更容易编程实现,空间耗用更少:后缀数组可用于解决最长公共子串问题,多模式匹配问题,最长 ...
- 剑指 Offer 29. 顺时针打印矩阵 + 蛇形矩阵 + 模拟 + 思维题
剑指 Offer 29. 顺时针打印矩阵 Offer_29 题目描述: 题解分析: 题目的初衷是将这道题当做一个简单题处理 这道题一开始想的太复杂了,其实可以参考迷宫广度优先搜索的过程,只不过在选定一 ...
- [PHP] 算法-顺时针打印矩阵的PHP实现
1.行数和列数取出来row,col,圈数就是 (较小值-1)/2+1 2.外层循环控制圈数,内层四个for循环,i 3.第一个for循环,从左到右,j=i;j<col-i;j++;j<; ...
- 【剑指offer】顺时针打印矩阵
转载请注明出处:http://blog.csdn.net/ns_code/article/details/26053049 剑指offer上的第20题,九度OJ上測试通过. 题目描写叙述: 输入一个矩 ...
- 剑指Offer(十九):顺时针打印矩阵
剑指Offer(十九):顺时针打印矩阵 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baid ...
- 剑指offer---1、顺时针打印矩阵
剑指offer---1.顺时针打印矩阵 一.总结 一句话总结: 谋而后动+多做:还是要谋而后动,但是怎么谋而后动,很有学问,做好的方式就是多做 问题就这些问题:解决了就好了,比如php多维数组 面试的 ...
随机推荐
- bzoj 2132 圈地计划【最小割+dinic】
对于网格图,尤其是这种要求相邻各自不同的,考虑黑白染色 对于这张染色后图来说: 对于每个黑格: 表示初始时选择商业区: s点向它连商业区收益的流量,它向t点连工业区收益的流量: 割断S侧的边说明反悔, ...
- springboot(十一)SpringBoot任务
github地址: https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service 1 ...
- JAVA中抽象类不可以实例化,却可以创建数组
这是我定义的一个抽象类: 如果你试图创建一个对象,当然是不行的,抽象类不能用new运算符创建对象. 这是错误提示,还记得instantiate这个单词吗?在我的这篇随笔第二篇(那些JAVA程序BUG中 ...
- Noip2014生活大爆炸版石头剪刀布【水模拟】
模拟暴力也要优雅. https://www.luogu.org/problemnew/show/P1328 像我这种蒟蒻就会敲无数个ifelse qaq. 可以优雅地进行预处理一下. 膜法真是好东西q ...
- C++this详解
以前对this指针误解挺多的,在这里单独写一篇进行总结,有不对之处,欢迎指正批评! 一.问题 1.一个类中的不同对象在调用自己的成员函数时,其实它们调用的是同一段函数代码,那么成员函数如何知道要访问哪 ...
- Spark SQL概念学习系列之Spark SQL入门
前言 第1章 为什么Spark SQL? 第2章 Spark SQL运行架构 第3章 Spark SQL组件之解析 第4章 深入了解Spark SQL运行计划 第5章 测试环境之搭建 第6章 ...
- 使用 Suricata 进行入侵监控(一个简单小例子访问百度)
前期博客 基于CentOS6.5下Suricata(一款高性能的网络IDS.IPS和网络安全监控引擎)的搭建(图文详解)(博主推荐) 1.自己编写一条规则,规则书写参考snort规则(suricata ...
- 快速体验openstack-用devstack安装openstack
官网安装说明: --2014年11月15日14:14:21 安装环境:Ubuntu12.04,安装官网的说明遇到了小问题,记录在这里 --http://docs.openstack.org/devel ...
- hihocoder 神奇字符串
思路: 暴力,模拟. 实现: #include <iostream> #include <algorithm> #include <cstdio> #include ...
- windows server 2008 r2 IIS7下网站配置 只允许指定的IP地址访问
步骤一.找到ip地址和域限制 步骤二.添加全部拒绝 步骤三.添加允许访问的ip地址(局域网填写局域网ip,公网填写公网ip) 步骤四:如果想要拒绝某些ip访问,直接在规则中添加拒绝条目就可以