单链表判断是否有环

  1. 使用set数据结构,依次判断每个结点的next指针是否有重复,重复点即为入环点
  2. 使用快慢指针的方式,使用两个指针依次遍历链表,快指针一次走两个结点,慢指针一次只走一个结点,若两指针相遇,则有环,相遇后,慢指针停在原地,快指针放在链首,两指针均以一次一步的速度继续向下走,第一次相遇点即为入环点。

判断并找到两个单链表相交点

首先用上述方法判断每个链表是否有环,根据有无环可将情况分为三种

(1)、两单链表均无环

则首先遍历两链表,分别得到最后一个结点,和链表长度,若两最后一个结点地址相同,说明有相加,此时计算链表长度差值,使用两个指针,一个指针从长链表首先走差值步,第二个指针从短链表首开始,两指针再同时以相同速度出发,他们第一个相同的结点即为相交点。

(2)一个链表有环,另一个链表无环

这种情况是不可能会相交的

(3)两个链表都有环


同样会有这三种情况,对于第二种只需判断两个有环链表的入环点是否相同,是则为第二种;若入环点不相同,则从其中一个环的入环点继续向下遍历循环一整圈,若其中经过另一个链表的入环点则为第三种情况,相交点可为任意链表的入环点,否则为第一种情况不相交。

二叉树

  • 三种遍历方式(先序头左右,中序左头右,后序左右头)的递归和非递归遍历(压栈)
  • 层序遍历的实现(先入先出队列实现)
  • 寻找最大层的两种方法:1、使用哈希表记录每个节点的层数 2、高级方法不使用哈希表

搜索二叉树

节点始终大于左孩子,小于右孩子
判断:使用中序遍历看是否为升序

完全二叉树

判断:使用层序遍历每个节点,满足下列条件

  1. 任意节点有右节点无左节点
  2. 再满足1条件情况下,如果遇到了第一个左右子节点不全的节点,那么其后面遍历的节点都是叶节点

平衡二叉树

每一个节点的左右子树的高度差小于2
这类问题可以使用递归套路(树形动态规划),因为对于每个节点,我们都要求其左右子树为平衡二叉树,且左子树和右子树的高度差小于2,那么我们使用递归函数时需要返回两个数字:

  • bool 是否为平衡二叉树
  • int 以该节点为头节点的字数的高度

那么对于叶节点,其自然返回的值为:(是平衡二叉树,高度为0)
如何解这个递归在于:利于其左右字数返回的数据判断是否符合平衡二叉树的条件,并选择左右子树中最大的高度再加一作为该子树的高度,返回给其父节点。

同样这个套路也可用再判断搜索二叉树中,每一个节点需要向其父节点返回的数据有:

  1. 是否为搜索二叉树
  2. 最大值
  3. 最小值
    那么一个节点利用其左右字数返回的数据可以判断其是否为搜索二叉树,并计算其最大值和最小值。

树形DP

  • 罗列条件情况
  • 从左右子树拿条件

其基本的代码结构为:

  • 设置返回数据的结构(构造函数)
  • 设置递归流程,要求对空节点进行数据的初始化
  • 在主函数对头结点调用递归

满二叉树

同样使用树形DP方法可以解决:

寻找两节点o1,o2在以head为头结点的二叉树中的最小公共父节点LCA

方法1:
在遍历树时,将每个节点的其本身包括所有父节点都存储在一个集合set中,并利用哈希表将每个结点及其父节点集合联系在一起,当要查找两节点的CLA时,只需使用其中一个节点的父节点集合,在另一节点不断向上找其父节点在集合中检索,最先匹配的即为所求

方法2:

分两种情况:

  • o1是o2的LCA,或o2是o1的LCA
  • o1,o2互不为LCA,必须向上才能找到

寻找后继节点

已知每个节点都有指向其父节点的指针parent,注意:后继节点是指在中序遍历中该节点的下一个节点
此题要理解的中序遍历的结构:

  • 当该节点有右子树时:其后继节点为右子树的最左节点
  • 当该节点无右子树时:需要利用parent向上寻找,一个节点(有左子树)的前序节点是其左子树上最右边的节点

折纸问题


当我们实际操作时会发现一个规律,构造一个左子树头结点始终为‘凹’,右子树头结点始终为‘凸’的满二叉树,那么该二叉树的中序遍历结果结尾所求
递归的过程很类似于递归中序遍历的代码

#include<iostream>
#include<stdlib.h>
#include<vector>
#include<map>
#include<string>
#include<set>
#include<queue>
#include<stack>
using namespace std;class Node {//结点
public:int value;int in;//入度int out;//出度vector<Node> nexts;vector<Edge> edges;Node(int value) {this->value = value;in = 0;out = 0;nexts = vector<Node>();edges = vector<Edge>();}
};
class Edge {//有向边
public:int weight;Node from;Node to;Edge(int weight,Node from, Node to) {this->weight = weight;this->from = from;this->to = to;}
};
class Graph {//图
public:map<int, Node> nodes;set<Edge> edges;Graph() {nodes = map<int, Node>();edges = set<Edge>();}
};
//以上是我们建立的常用图结构,而在做题时会遇到不同结构的图,需要设置一个接口将其转换为我们
//所熟悉的图结构,例:给出一个二维数组,每一行代表一个有向边其中matrix[i][0]为起点,
//matrix[i][1]为终点,matrix[i][2]为权重,设置接口如下:
Graph creatGraph(int matrix[][3]) {int length = sizeof(matrix) / sizeof(matrix[0]);Graph graph = Graph();for (int i = 0; i < length; i++) {int from = matrix[i][0];int to = matrix[i][1];int weight = matrix[i][2];if (graph.nodes.find(from) == graph.nodes.end()) {graph.nodes.insert({ from, Node(from) });}if (graph.nodes.find(to) == graph.nodes.end()) {graph.nodes.insert({ to, Node(to) });}Node fromNode = graph.nodes.at(from);Node toNode = graph.nodes.at(to);Edge newEdge = Edge(weight, fromNode, toNode);fromNode.nexts.push_back(toNode);fromNode.out++;toNode.in++;fromNode.edges.push_back(newEdge);graph.edges.insert(newEdge);}return graph;
}//宽度优先遍历 BFS
void bfs(Node node) {queue<Node> queue;set<Node> set;queue.push(node);set.insert(node);//用set来保证检查去重的机制while (!queue.empty()) {Node cur = queue.front();queue.pop();cout << cur.value << endl;for (auto it = cur.nexts.begin(); it != cur.nexts.end(); it++) {if (set.find(*it) != set.end()) {set.insert(*it);queue.push(*it);}}}
}
//深度优先遍历,利用栈
void dfs(Node node) {stack<Node> stack;set<Node> set;stack.push(node);set.insert(node);cout << node.value << endl;while (!stack.empty()) {Node cur = stack.top();stack.pop();for (auto it = cur.nexts.begin(); it != cur.nexts.end(); it++) {if (set.find(*it) != set.end()) {stack.push(cur);stack.push(*it);set.insert(*it);cout << (*it).value << endl;break;}}}
}

拓扑排序算法

即在完成一项工程时,不同的工序之间有着前后依赖的关系,后一项工序必须等待前一项工序完成,如此形成一个有向图并且不存在环,我们要解决如何对每个工序进行排序的问题
算法很简单:寻找图中入度为0的节点将其放在序列中,并在图中删除该节点及其所有的影响,再次寻找入度为0的节点,循环直至将所有结点排序

//拓扑排序
vector<Node> sortedTopology(Graph graph) {map<Node, int> inMap;queue<Node> zeroInQueue;for (auto it = graph.nodes.begin(); it != graph.nodes.end(); it++) {inMap.insert({ it->second,it->second.in });if (it->second.in == 0) {zeroInQueue.push(it->second);}}vector<Node> result;while (!zeroInQueue.empty()) {Node cur = zeroInQueue.front();zeroInQueue.pop();result.push_back(cur);for (auto it = cur.nexts.begin(); it != cur.nexts.end(); it++) {inMap[*it] -= 1;if (inMap.at(*it) == 0) {zeroInQueue.push(*it);}}}return result;
}

最小生成树(无向图)

kruskal算法

从边考虑,从权重有小到大依次选取所有边,若添加该边会形成环则不添加
难点在于如何实现判断是否成环的机制,这个机制能实现集合的查询和集合的合并功能,比如要连接A和B的边,那么查询A和B所在的集合,若他们所在同一个结合中,则该边不添加,会形成环,否则说明改变可以添加不形成环,并将A和B所在的集合合并为一个集合。

跟着左程云学面试算法相关推荐

  1. 左程云牛客算法初级班笔记

    第一课 第二课 第三课 第四课 第五课 第六课 第七课 第八课 个人的上课笔记 记录了一些算法题细节的理解要点 第一课 估计递归大小复杂度的通式 a子过程样本量 b子过程发生了多少次 0: 除去子过程 ...

  2. 堆排序算法java左程云_堆排序算法以及JAVA实现

    堆的定义如下: n个元素的序列{k0,k1,...,ki,-,k(n-1)}当且仅当满足下关系时,称之为堆. " ki<=k2i,ki<=k2i+1;或ki>=k2i,ki ...

  3. 牛客网左程云直通BAT算法课10元优惠码

    优惠码:A5ZLzAV 购课链接:http://www.nowcoder.com/courses/1?coupon=A5ZLzAV

  4. CSDN专访左程云,算法之道

    算法的庞大让很多人畏惧,程序员如何正确的学习并应用于面试.工作中呢?今天,CSDN邀请了IBM软件工程师.百度软件工程师.刷题5年的算法热爱者左程云,来担任CSDN社区问答栏目的第二十六期嘉宾,届时会 ...

  5. 左程云:程序员该如何学习算法?

    大家好,我是左程云.我本科就读于华中科技大学.硕士毕业于在芝加哥大学.先后在IBM.百度.GrowingIO和亚马逊工作,是一个刷题7年的算法爱好者. 我是<程序员代码面试指南--IT名企算法与 ...

  6. 一周刷爆LeetCode,算法da神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解 笔记

    一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解 笔记 教程与代码地址 P1 出圈了!讲课之外我们来聊聊 ...

  7. 一看“左程云:200道算法与数据结构”,二刷“阿里云:70+算法题、30种大厂笔试高频知识点”,3月过去终于挺进我梦中的字节!

    不管是学生还是已经工作的人,我想彼此都有一个相同的梦想:进大厂! 眼看着2020年还有个三十来天就要完美收尾了,那么如何才能在未来三个月弯道超车赶上"金三银四的春招",进入梦寐以求 ...

  8. 左程云算法笔记总结-基础篇

    基础01(复杂度.基本排序) 认识复杂度和简单排序算法 时间复杂度 big O 即 O(f(n)) 常数操作的数量写出来,不要低阶项,只要最高项,并且不要最高项的系数 一个操作如果和样本的数据量没有关 ...

  9. 【左程云Java算法】Chapter1-5:用一个栈实现另一个栈的排序

    [左程云Java算法]Chapter1-5:用一个栈实现另一个栈的排序 [题目] 用一个栈实现另一个栈的排序 [要求] 一个栈中元素的类型为整型,现在想将该栈从顶到底按从大到小的顺序排序,只许申请一个 ...

最新文章

  1. 为什么说++i的效率比i++高?
  2. Linux 爱好者的飞行棋:sudo
  3. 神经网络不收敛的 11 个原因,加实践感悟
  4. 强烈推荐10 个机器学习教程!(含视频链接)
  5. python相对路径找不到文件_Python相对路径从子文件夹导入
  6. 【WebRTC---入门篇】(四)WebRTC设备管理
  7. 第五节: EF高级属性(一) 之 本地缓存、立即加载、延迟加载(不含导航属性)
  8. idea怎么把代码放到git_在IntelliJ IDEA中同步代码到华为云git仓库 (on windows)
  9. 初学JAVA——方法重载练习
  10. Angular 发布首个正式的路线图
  11. 12 个顶级 Bug 跟踪工具
  12. Java递归算法经典实例
  13. 计算机 仿真 流体力学剪切应力,基于人体血管B型主动脉夹层三维建模及血流动力学仿真研究...
  14. JDK动态代理(介绍理解,如何实现)
  15. Android Studio Entry name *.xml collided解决方案
  16. 开源免费CRM云端的客户管理系统SuiteCRM简介
  17. 移动硬盘无法访问怎么办?还能恢复数据吗?
  18. 软件人员推荐书目(都是国外经典书籍!!!)
  19. MATLAB程序设计与应用 4.1 M文件
  20. android支付宝运动修改器,支付宝运动步数修改器下载-无需root刷支付宝运动步数工具下载_飞翔下载...

热门文章

  1. corner net
  2. GPL协议中国第一案尘埃落定,相关开源软件应如何风控?
  3. java web 服务器推送技术--comet4j
  4. ListView详解
  5. Linux安装ES最新版
  6. 博客与微博有什么区别_陕南赤子_新浪博客
  7. CoralSwap或将成为OKExChain上的下一个爆款?
  8. 那些优秀的开发者----汪宇杰:从重视细节,到成就技术专家
  9. FlashFXP 3.6 Final(正式版)注册码
  10. PCB Layout调管脚设计指南