刷题之旅2020.12.05
2020.12.05
1.前中后序 递归/非递归 实现
一、使用栈模拟递归实现过程
先序/中序
public List preinOrder2(TreeNode root){if(root==null)return;Stack<TreeNode> s=new Stack<>();List list = new LinkedList();while(root!=null || !s.isEmpty()){//不断往左子树方向走,每走一次就将当前节点保存到栈中//这是模拟递归的调用if(root != null){list.add(root.val); //这里访问顺序是先序s.push(root);root = root.left;//当前节点为空,说明左边走到头了,从栈中弹出节点并保存//然后转向右边节点,继续上面整个过程}else{root = s.pop();list.add(root.val); //这里访问顺序是中序root = root.right;}}
}
后序(模拟递归实现)
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<Integer>();if (root == null) {return res;}Deque<TreeNode> stack = new LinkedList<TreeNode>();TreeNode prev = null;while (root != null || !stack.isEmpty()) {while (root != null) {stack.push(root);root = root.left;}root = stack.pop();if (root.right == null || root.right == prev) {res.add(root.val);prev = root;root = null;} else {stack.push(root);root = root.right;}}return res;}
}
后序(利用前序实现「根-左-右」—> 「右-左-根」—> 「左-右-根」)
public List postorder(TreeNode root){TreeNode node = new TreeNode();Stack stack = new Stack();List list = new LinkedList();while(!stack.isEmpty() || root!=null){if(root != null){//头插法List.addFirst(root.val);stack.push(root);//优先访问右子树root = root.right;}else {root = stack.pop();root = root.left;}}return list;
}
颜色标记法模板
其核心思想如下:
- 使用颜色标记节点的状态,新节点为白色,已访问的节点为灰色。
- 如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点、自身、左子节点依次入栈。
- 如果遇到的节点为灰色,则将节点的值输出
class Solution {class ColorNode {TreeNode node;String color;public ColorNode(TreeNode node,String color){this.node = node;this.color = color;}}public List<Integer> inorderTraversal(TreeNode root) {if(root == null) return new ArrayList<Integer>();List<Integer> list = new ArrayList<>();Stack<ColorNode> stack = new Stack<>();stack.push(new ColorNode(root,"white"));while(!stack.empty()){ColorNode cn = stack.pop();if(cn.color.equals("white")){// 入栈顺序 对应于访问结果顺序(这里为中序,对应 右 根 左)if(cn.node.right != null) stack.push(new ColorNode(cn.node.right,"white")); stack.push(new ColorNode(cn.node,"gray"));if(cn.node.left != null)stack.push(new ColorNode(cn.node.left,"white"));}else{list.add(cn.node.val);}}return list;}
}
另一种奇技淫巧,直接判断栈元素是否为TreeNode
public List<Integer> inorderTraversal(TreeNode root) {Stack<Object> stack = new Stack<>();List<Integer> list = new ArrayList<>();if (root == null)return list;stack.push(root);while (!stack.isEmpty()) {Object pop = stack.pop();if (pop instanceof TreeNode) {// 入栈顺序 对应于访问结果顺序(这里为中序,对应 右 根 左)TreeNode treeNode = (TreeNode) pop;if (treeNode.right != null) {stack.push(treeNode.right);}stack.push(new Integer(treeNode.val));if (treeNode.left != null) {stack.push(treeNode.left);}} else {list.add((Integer)pop);}}return list;}
链表
1.两两交换链表中节点 (leetcode24)
思路:可以使用迭代或者递归实现
迭代实现:
新建哑结点nHead
,令nHead.next = head
,令 temp
表示当前到达的节点,初始时 temp = nHead
。每次需要交换 temp
后面的两个节点即可,如果 temp 的后面没有节点或者只有一个节点,则没有更多的节点需要交换,因此结束交换。否则,获得 temp 后面的两个节点 node1 和 node2,通过更新节点的指针关系实现两两交换节点。
public ListNode swapPairs(ListNode head) {if (head == null || head.next == null)return head;ListNode nHead = new ListNode(-1);nHead.next = head;ListNode temp = nHead;while (temp.next != null && temp.next.next != null) {ListNode nNext = temp.next.next;temp.next.next = nNext.next;nNext.next = temp.next;temp.next = nNext;temp = nNext.next;}return nHead.next; }
递归实现:
终止条件为head == null || head.next == null;
递归思路就是假设head.next.next后面已经完成两两交换,并返回,即temp = swapPairs(head.next.next);
则单次递归执行逻辑为:ListNode newHead = head.next; head.next = temp;newHead.next = head;
class Solution {public ListNode swapPairs(ListNode head) {if (head == null || head.next == null) {return head;}ListNode newHead = head.next;head.next = swapPairs(newHead.next);newHead.next = head;return newHead;}
}
2.反转链表||(leetcode92)
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
反转从位置m到n的链表。思想:在第m节点的前一个位置(这里指向1)设为pre节点,利用cur指针(这里指向2)依次将cur节点的后置节点插入到pre后面,执行逻辑为:ListNode nxt = cur.next;cur.next = nxt.next;nxt.next = pre.next;pre.next = nxt;
public ListNode reverseBetween(ListNode head, int m, int n) {if (head == null) return null;ListNode pre = new ListNode(-1);ListNode nHead = pre;pre.next = head;for (int i=1; i<m; i++) {pre = pre.next;}ListNode cur = pre.next;for (int i=m; i<n; i++) {ListNode nxt = cur.next;cur.next = nxt.next;nxt.next = pre.next;pre.next = nxt;}return nHead.next;}
刷题之旅2020.12.05相关推荐
- 牛客网的刷题之旅——2020/8/6
机器人走方格II 题目链接: https://www.nowcoder.com/questionTerminal/b3ae8b9782af4cf29253afb2f6d6907d 题目描述 有一个Xx ...
- 牛客网的刷题之旅——2020/7/30
寻宝 题目链接:https://www.nowcoder.com/questionTerminal/59aff3b7a9094432893302c9ee7794e8 题目描述 亮亮解出了卷轴隐藏的秘密 ...
- LeetCode 刷题之旅(2020.05.22)——105. 从前序与中序遍历序列构造二叉树(中)
LeetCode 刷题之旅(2020.05.22)--105. 从前序与中序遍历序列构造二叉树(中) 题目: 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如, ...
- LeetCode刷题之旅
LeetCode刷题之旅 一.链表 1.链表逆序(leetcode 206.Reverse Linked List)esay 题目描述:已知链表头节点指针head,将链表逆序. 思路:从链表的头节点依 ...
- Leetcode刷题之旅1
Leetcode刷题之旅1 先从剑指offer66题开始刷 链表可创建dummy哑节点指向头指针,目的是为了对头节点进行操作 例子:删除链表中重复节点 确定有限状态自动机 例子:剑指offer20 表 ...
- 重走长征路---OI每周刷题记录---4月12日 2015
总目录详见https://blog.csdn.net/mrcrack/article/details/84471041 做题原则,找不到测评地址的题不做.2018-11-28 重走长征路---OI每周 ...
- 如何正确刷题计算机考研,2020考研:4个方法教你数学如何正确刷题!
时间飞逝,不知不觉进入暑期尾声,作为考研课程中的公共课程,数学在其中起着至关重要的作用.现阶段不少同学都少不了题海战术,但是大家不要盲目地刷,那如何才能通过做题来提高数学成绩呢?下面小编教你正确的数学 ...
- leetcode数组相关简单习题,玉米迪迪的刷题之旅(*╹▽╹*)
好啦好啦!我今天开始重鼓信心刷题啦!也不知道怎么回事一道简单的数组题开始有了思路,却总是写不出来,但是也就是看了别的大佬的思路以及自己的回忆,突然发现!这个题的做法我的老师讲过!一下子又发现我回忆起来 ...
- 【系统集成项目管理刷题专题】第12章—项目沟通管理和干系人管理
此专题记录从3月25日开始备考软考中级的全过程,2021年上半年第一次参与裸考两门都只考了35分.这次必须给过了,此系列文章为证. 注:文章内容为科科过章节刷题笔记 第一遍刷题笔记,第二遍框架逻辑 第 ...
最新文章
- unity水管工_我是如何从30岁的管道工转变为32岁的Web开发人员的
- 清华男女图鉴 | 有电车会拍照,我在清华还是找不到女朋友
- java的total_Java LabelResourcePool.totalNum方法代码示例
- java 文本工具类_干货:排名前16的Java工具类
- 新一代Notebook神器出现,Jupyter危险了!
- 构建地理上分散的网络之4点论证
- 如何将 Linux 系统转移至 LVM 卷
- liferay search container的两种实现方式
- 不应该通过类实例访问静态成员 解决方法_今天说一说php中的类与对象
- 杭电1998 奇数阶魔方
- 宝塔面板 php关闭拓展,宝塔Linux面板中PHP如何安装扩展及禁用函数?
- Bailian4030 统计单词数【文本处理】
- 盘点八个程序员必须知道的代码编辑器
- 产品经理三大证书,考哪个好
- XML 教程(一文彻底搞懂XML)
- 机器学习-准确率、灵敏度、特异度、PPV、NPV、F1计算方法
- h3c路由器msr2600-10,msr3600-28调试记录
- 【深入kotlin】 - 匿名函数、闭包和接收者
- 猜秘密三位数(人、机互相猜)小游戏
- syslinux 启动后显示SYSLINUX 5.01H. Peter Anvin et al