剑指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 ...
随机推荐
- 为windows phone listbox 添加触摸倾斜效果
在开发windows phone程序时,经常会用到listbox或者是longlistselector等列表控件.当点击时没有触摸效果体验会稍差一些,像windows phone中的设置页面一样,点击 ...
- Luogu3147 USACO16OPEN 262144(动态规划)
感觉上这个题是可以直接暴力的,每次根据一段连续最小值个数的奇偶性决定是否划分区间,递归处理.然而写起来实在太麻烦了. 设f[i][j]为以i为左端点合并出j时的右端点.则有f[i][j]=f[f[i] ...
- POJ2724:Purifying Machine——题解
http://poj.org/problem?id=2724 描述迈克是奶酪工厂的老板.他有2^N个奶酪,每个奶酪都有一个00 ... 0到11 ... 1的二进制数.为了防止他的奶酪免受病毒侵袭,他 ...
- BZOJ3076 & 洛谷3081:[USACO2013 MAR]Hill Walk 山走——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=3076 https://www.luogu.org/problemnew/show/P3081#sub ...
- 从零开始学Linux系统(五)用户管理和权限管理
权限管理: 常识: chmod U-所有者 g-所属组 O-其他人r-4-可读 w-2-可写 x-1-可执行 s-4-SetUID s-2-SetGID t-1-粘着位 注:目 ...
- Visual Studio 2010如何利用宏
最近在做后台代码的拆分,由于机器升级,原来装的添加注释的插件不能用了. 看来只有自己想办法了,看了下利用宏添加注释与把项目展开.折叠的方式: 参考了以下几个内容: 1.Visual Studio 20 ...
- React的getDefaultProps和getInitialState
getDefaultProps 不是获取默认props,而是设置默认props,主要用在ES5的React写法中getInitialState 不是获取默认State,而是设置初始的state,主要是 ...
- NOIP系列
NOIP2015运输计划 唉 真是 这题 卡死我了 tarjan离线lca复杂度O(n) 最后各种卡常,多交几遍才A(洛谷104ms) %%%zk学长609ms 注意二分的时候左边界要定成0 根据题意 ...
- 【队列】【P2827】【NOIP2016D2T3】蚯蚓
传送门 Description 本题中,我们将用符号 $\lfloor c \rfloor$ 表示对 $c$ 向下取整,例如:$\lfloor 3.0 \rfloor = \lfloor 3.1 \r ...
- 剑桥offer系列(1~10)
1.题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路:从左下开始, ...