剑指offer中数据结构与算法部分学习
2.3.4 树
遍历:前中后序,宽度优先。
二叉树的特例:二叉搜索树、堆(最大堆和最小堆,用于找最值)、红黑树(c++ STL中的很多数据结果就是基于这实现的);
题7-重建二叉树:递归,设置四个位点;
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if(pre.size()!=vin.size()||vin.size()==) return nullptr;
return Construct(,pre.size()-,,vin.size()-,pre,vin);
}
TreeNode* Construct(int prestart,int preend,int vinstart,int vinend,const vector<int> &pre,const vector<int> &vin){
if(prestart>preend) return nullptr;
TreeNode* root=new TreeNode(pre[prestart]);
for(int i=vinstart;i<=vinend;i++)
if(pre[prestart]==vin[i]){
root->left=Construct(prestart+,prestart+i-vinstart,vinstart,i-,pre,vin);
root->right=Construct(prestart+i-vinstart+,preend,i+,vinend,pre,vin);
break;
}
return root;
}
};
题8-二叉树的下一个节点
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode==nullptr) return nullptr;
if(pNode->right!=nullptr){
pNode=pNode->right;
while(pNode->left!=nullptr){
pNode=pNode->left;
}
return pNode;
}
else{
if(pNode->next==nullptr)
return nullptr;
else{
if(pNode==pNode->next->left)
return pNode->next;
else{
while(pNode->next!=nullptr){
if(pNode==pNode->next->left)
return pNode->next;
pNode=pNode->next;
}
return nullptr;
}
}
}
}
};
2.3.5 栈和队列
题9-两个栈实现队列:一个用于插入,一个用于删除,增加判空操作,每次插入/删除操作后只有一个栈是有数据的;
2.4 算法和数据结构
递归/循环,排序/查找,搜索路径(回溯法),最优解(动态规划),贪心,位运算(与、或、异或、左右移)
2.4.1 递归和循环
如果面试官没有要求,多采用递归;递归存在时间效率和调用栈溢出的问题;
题10-斐波那契数列:递归效率低,采用循环O(n),也可以用到数学公式用递归O(logn),青蛙跳和格子都是这个问题;
2.4.2 查找和排序
顺序查找、二分、哈希表查找、二叉排序树
交换使用swap函数,使用随机数配合递归来进行快排;
面试官的交流:要问排序的是什么数据、数据量,能用多少辅助空间?明确场景
题11-旋转数组的最小数字:O(n)到O(logn),使用二分,但是要有特殊处理,例如如果两个位点元素相等,则内部的应该进行顺序查找;
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size()==0) return 0;
int low=0,high=rotateArray.size()-1,mid=(low+high)/2;
if(rotateArray[low]<rotateArray[high]) return rotateArray[low];
if(high<2) return rotateArray[high];
while(low!=high-1){
if(rotateArray[low]<rotateArray[high]) return rotateArray[low];
if(rotateArray[low]==rotateArray[mid]&&rotateArray[mid]==rotateArray[high]){
int min=rotateArray[low];
for(int i=low+1;i<=high;i++)
if(min>rotateArray[i])
min=rotateArray[i];
return min;
}
if(rotateArray[low]>rotateArray[mid]){
//low=low+1;
high=mid;
mid=(low+high)/2;
}
if(rotateArray[high]<rotateArray[mid]){
low=mid;
mid=(low+high)/2;
}
}
return rotateArray[low+1];
}
};
2.4.3 回溯法
适合用递归实现,其实也可以用堆栈。
题13-机器人的运动规划:本来觉得两轮遍历就可以找到不可以到达的格子,后来发现是不对的,所以还是用了回溯去找
class Solution {
public:
int movingCount(int threshold, int rows, int cols)
{
if(threshold<=0||rows<=0||cols<=0) return 0;
bool *visited=new bool[rows*cols];
for(int i=0;i<rows*cols;i++)
visited[i]=false;
int res=getCount(rows,cols,0,0,threshold,visited);
delete[] visited;
return res;
}
int getCount(int rows,int cols,int row,int col,int threshold,bool* visited){
int count=0;
if(!visited[row*cols+col]&&(getSum(row,col)<=threshold)&&row>=0&&col>=0&&row<rows&&col<cols){
visited[row*cols+col]=true;
count=1+getCount(rows,cols,row-1,col,threshold,visited)+getCount(rows,cols,row+1,col,threshold,visited)+getCount(rows,cols,row,col-1,threshold,visited)+getCount(rows,cols,row,col+1,threshold,visited);
}
return count;
}
int getSum(int rows,int cols){
int sum=0;
while(rows>0||cols>0){
sum+=(rows%10+cols%10);
rows/=10;
cols/=10;
}
return sum;
}
};
2.4.4 动态规划与贪婪算法
动规:
- 分解成很多子问题;
- 整体的问题依赖于子问题
- 子问题之间还有相互重叠的更小的子问题
从上往下分析,从下往上求解(顺序先计算出小问题的最优解并存储下来)
题-剪绳子:使用动态规划来做(两个循环 O(n方));用贪婪法(o(1)的时间和空间,需要证明);
2.4.5 位运算
与、或、异或、左右移(计算效率比乘除高);
注意右移时如果是负数的话补的是1,还有把整数减去1之后与原来的数做位与运算后结果相当于把整数的二进制表示中最右边的1变为0,很多二进制问题可以用这个套路;
题-二进制中1的个数
class Solution {
public:
int NumberOf1(int n) {
int count=0;
while(n){
count++;
n=n&(n-1);
}
return count;
}
};
剑指offer中数据结构与算法部分学习的更多相关文章
- 剑指offer中经典的算法题之从头到尾打印链表
话不多说上代码: 我自己的算法是: /** * public class ListNode { * int val; * ListNode next = null; * * ListNode(int ...
- 剑指Offer——知识点储备-常用算法
剑指Offer--知识点储备-常用算法 快速排序 注:若排序是有序的,采用快排,则退化为冒泡排序. 解决这个问题,采用两个选取基准的方法 (1)随机选取基数(在这个区间内随机取一个数) 出现的恶劣情况 ...
- 剑指offer之O(1)算法删除指针所指向的节点
题目如图: 1.把要删除pToBeDeleted的节点的后面节点覆盖点要删除的节点pToBeDeleted 2.要考虑如果删除的节点是最后一个节点怎么办 3.要考虑如果总共只有一个节点,删除的是头结点 ...
- 剑指offer——已知二叉树的先序和中序排列,重构二叉树
这是剑指offer中关于二叉树重构的一道题.题目原型为: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2, ...
- 【剑指Offer学习】【面试题:二维数组中的查找】PHP实现
最近一直看剑指Offer.里面很多算法题.于是就想着用PHP来显示一下. 题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. 请完成一个函数,输入这样的 ...
- 《剑指offer》算法题第一天
按照个人计划,从今天开始做<剑指offer>上面的算法题,练习平台为牛客网,上面对每道题都有充分的测试实例,感觉还是很不错的.今天下午做了四道题,分别为: 1. 二叉树的深度(书55题) ...
- 面试题目——《剑指Offer》
1.把一个字符串转换成整数——<剑指Offer>P29 2.求链表中的倒数第k个结点——<剑指Offer>P30 3.实现Singleton模式——<剑指Offer> ...
- 剑指Offer——归并排序思想应用
剑指Offer--归并排序思想应用 前言 在学习排序算法时,初识归并排序,从其代码量上感觉这个排序怎么这么难啊.其实归并排序的思想很简单:将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列 ...
- 7、斐波那契数列、跳台阶、变态跳台阶、矩形覆盖------------>剑指offer系列
题目:斐波那契数列 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). f(n) = f(n-1) + f(n-2) 基本思路 这道题在剑指offe ...
随机推荐
- C# 跨服务大文件复制
跨服务的大文件复制,肯定要和本地大文件复制一样,分多次传递,要不然内存也承受不了,下面就说下如何实现大文件的跨服务复制······ 首先肯定要建立一个WCF的服务以及对应的客户端来测试服务,此方法请参 ...
- SocketServer-实现并发处理
Python提供了两个基本的socket模块. 一个是socket,它提供了标准的BSD Socket API:另一个是socketServer,它提供了服务器中心类,可以简化网络服务器的开发,其实就 ...
- IntelliJ IDEA2018注册
第一步:0.0.0.0 account.jetbrains.com及0.0.0.0 www.jetbrains.com 添加到hosts文件 第二步:进入 http://idea.lanyus.co ...
- BZOJ1031:[JSOI2007]字符加密——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1031 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密 ...
- AtCoder Grand Contest 031 B - Reversi(DP)
B - Reversi 题目链接:https://atcoder.jp/contests/agc031/tasks/agc031_b 题意: 给出n个数,然后现在你可以对一段区间修改成相同的值,前提是 ...
- SQL Server2000安装教程图解
sql2000安装教程图解... ================================= 第一部分:下载所需要的安装包: 可以自己在网上百度了之后下载--或是直接从我已打包好的群里下载 = ...
- php中error_reporting
error_reporting(255);是列出所有提示error_reporting(0);是不显示所有提示建议使用error_reporting(7);只显示严重错误1 E_ERROR 致命的运行 ...
- 【c#】winform 上传图片
1.拖拽上传图片 1.1.后台代码中修改窗体属性,添加 AllowDrop = true 1.2.给窗体添加拖拽事件,在事件列表找到拖拽 双击即可: 在 DragDrop 生成的方法中添加代码如下: ...
- 任何用户密码都能以sysdba角色登入
这是因为在安装Oracle的时候默认是使用了操作系统验证: 数据库用sysdba登录的验证有两种方式,一种是通过os认证,一种是通过密码文件验证:登录方式有两种,一种是在数据库主机直接登录(用os认证 ...
- JAVA--结果集已耗尽
有两个可能 1.rs ,state和conn没有关闭 rs.close(); state.close(); conn.close(); if(rs!=null) rs.close; if(sta ...