数组相关题(剑指office)

数组相关题
1.二维数组中的查找
2.调整数组顺序使得奇数位于偶数前
3.顺时针打印矩阵
4.判断一个数组是否是某二叉搜索树的后序遍历
5.n个整数的无序数组,找到每个元素后面比它大的第一个元素(O(n)):
6.数组中出现次数超过一半的数字:
7.最小的k个数:
8.连续子数组的最大和:
9.把数组排成最小的数:
10.数组中的逆序对:
11.长为N的数组中存放0~n-1,判断数组是否有重复:
12.构成乘积数组(B[i]=A[0]A[i-1]…A[i+1]A[n-1]):
13.数据流中的中位数:
14.滑动窗口的最大值:
15.矩阵中的路径(经典递归):
16.机器人的活动范围:
1.二维数组中的查找
题目
---->注意数组中数的规律;对数进行观察;左下角开始;

对于算法编程题,尤其数组要考虑数组中数字的规律;

2.调整数组顺序使得奇数位于偶数前
题目
---->使用index记录第一个偶数的索引;或使用两个数组;

注意每次奇数移前后,要更新index;
即index++;

3.顺时针打印矩阵
题目
—>标记数组法:
1.使用一维数组dx与dy标记方向,变量dir进行更改方向;
2.使用二维数组flag记录每一个元素是否为遍历的状态;

vector flag(row,vector(col));并使用双层循环初始化;

这里本来没有路,走的人多了便形成了路;
这里本来不会做,做的题多了便就会做了;

—>边界限定法:定义四个变量right;down;left;up;

每处理一个方向需要判断是否越界:up>down或left>right;
好的算法节省空间和时间;

4.判断一个数组是否是某二叉搜索树的后序遍历
题目
—>递归:使用两个一维数组分别保存小于的数集合和大于的数集合;并分别对其递归;

在统计小于数集合时,如果小于入;否则break;不要忘记break;

–>非递归:从最后一个数字开始判断;前面的数据合法情况分为:小于temp的集合、大于temp的集合;

做题时要分析题目信息,比如二叉搜索数的后序遍历性质;

5.n个整数的无序数组,找到每个元素后面比它大的第一个元素(O(n)):
vector FindMax(vector &num)
1
---->1.使用一个stack保持之前还没有找到的元素的索引,用最小值初始化一个res;并使用res保存结果;
2.如果s为空或者栈顶索引元素大于当前元素,当前索引如栈;
3.否则循环保存结果,最后将当前索引入栈;

//缩减版
vector FindFirstMax(vector num)
{
vector res(num.size(),INT_MIN);
stack s1;
for(int i=0;i<num.size();i++)
{
while(!s1.empty() && num[s1.top()]<num[i])
{
res[s1.top()]=num[i];
s1.pop();
}
s1.push(i);
}
return res;
}

6.数组中出现次数超过一半的数字:
题目
–>1. 使用pre记录前一个数,使用count记录前一个数出现的次数;当等加++;不等就–;当减到0时就更新pre和count;
如果存在某个数的次数大于size/2; 最后count>0;
—>2.map法;3.先排序在统计;

7.最小的k个数:
题目
---->1.先快排在截取(注意条件中符号不要取反)O(nlog(n));
---->2.滑动窗口(O(n*klog(k))),堆排序,适用于数据过大,且不修改原数据;

sort<v1.begin(),v1.end(),www.fdouyf.comless()> //less()为升序列;而greater()为降序;
v1.erase(v1.begin()+k-1);
v1.push_back();
1
2
3
STL的许多函数操作都是基于迭代器进行的;

8.连续子数组的最大和:
题目

---->使用curMax记录当前最大值和,max保存最好结果;
最后如果max<0,说明数组全为负数;

if(curSum>maxSum);
maxSum=curSum;
//有时并不是思路错了,而是语法出错;
//上面后面的语句不管if是否成立都会执行的;所有写代码需要谨慎;
if(curSum>maxSum)
maxSum=curSum;
数组排成最小的数:
题目
—>整数转为字符串to_string();字符串转为整数atoi(str.c_str());1.暴力法比较第i个元素与i之后元素的合并比较,i+j>j+i时,交换其位置;2.使用字符串比较方法(strcmp,compare等);

//sort函数的使用,参数三的定义,参数三为谓词,静态函数指针;所以Compare必须声明为静态的;
//结合to_string函数和atoi(str.c_str())函数;
static bool Compare(int a,int b)
{
string str1=to_string(a)+to_string(b);
string str2=to_string(b)+to_string(a);
return str1+str2< str2+str1;
}

静态方法没有this指针;

10.数组中的逆序对:
题目
----->1.使用归并排序:MergeOne函数,Merge函数(合法性判断l<r);
2.如果data[i]>data[j]时:count=count+(mid-i+1);

11.长为N的数组中存放0~n-1,判断数组是否有重复:
题目

—>利用数的规律:使得索引为i的位置存放数字numbers[i];如果索引i的位置已经存放i,那么有重复即i;

while(i!=numbers[i])

12.构成乘积数组(B[i]=A[0]A[i-1]…A[i+1]A[n-1]):
题目
---->一个变量res记录从前往后的A[i]累成;
计算从后前的累成;B[i]=res,res*=A[i];

13.数据流中的中位数:
题目
—>一个插入函数(并进行插入排序);一个计算函数;

数据流一般都是两个函数实现的,一个进一个出;

14.滑动窗口的最大值:
题目
----> 如下:

//从i=size-1开始;
vector temp(num.begin()+i-size+1,num.begin()+i+1);
//或者从i=0;外面定义一个temp;如果i<size-1,push,否则push,找max,再erase();
temp.erase(temp.begin()); //从temp中删除第一个元素;

15.矩阵中的路径(经典递归):
题目
---->定义全局变量col,row,dx,dy;
使用函数hasPath处理每一个点;

bool hasPath(char* matrix,char* str,int k,int i,int j)
{
if(k==strlen(str))
return true;
if((matrix+icol+j)!=www.64z206.com
(str+k)) //千万不要写成
(matrix+irow+j)了
return false;
char temp=
(matrix+icol+j); //(matrix+icol+j)等同于matrix[icol+j]
(matrix+icol+j)=’*’;
for(int d=0;d<4;d++)
{
if(hasPath(matrix,str,k+1,i+dx[d],j+dy[d]))
return true;
}
(matrix+icol+j)=temp;
return false;
}

如果定义matrix为 char* m=“abcdef”;那么m传个matrix时会出现:
出现异常:Segmentation fault;
正确的matrix实参定义:char ch[1000]=“abcdef”; char *m=ch;

16.机器人的活动范围:
题目
---->注意当前格不能进入,需要内外层判断Sumij(j)是否大于阈值,大于,那么该行之后的也不能进入;

题目意思是:但是不能进入行坐标和列坐标的数位之和大于k的格子;通过判断Sumij(j)>k, Sum(i)>k;
如果是当当前不能进入,那么之后的也不能进入时;判断的则是Sumij(i)+Sumij(j)>k;

注意:仔细读懂题意,为是什么在循环中判断的是Sumij(j)>k, Sum(i)>k,而不是Sumij(i)+Sumij(j)>k;
15,20,20
通过对比后者从(7,8)之后(7,9)就不进行了,而前者跳过(7,9),继续(7,10)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值