链表和树的leetcode题

news/2024/11/19 2:27:04/

基础新手

链表

注意事项

注意保存上下文环境。注意gc,不要有垃圾变量。换头结点注意考虑头

对于链表不要在乎是O(n)还是O(2n)

长短链表互换

习题

K个节点的组内逆序调整 ?

leetcode:K 个一组翻转链表

找n函数

逆转函数

第一组是否找齐

之后每组处理:start先指向下一组头,遍历完再指向尾

不在于算法,而在于coding能力

链表相加

注意长短链表互换,链表1结点+链表2结点+进位,注意最后进位需要补结点

阶段1:两个相加+进位 while(shortNode != null)

阶段2:单个链表+进位 while(longNode != null)

阶段3:链表结束,仍有进位,补结点 if(carry != 0)

上面三个阶段分别是3个循环

有序链表合并

注意换头,有一个为空就出循环

合并K个升序链表

leetcode:合并K个升序链表

利用小根堆,注意返回空

m条链表,总结点n个。时间复制度 O(log(m)*n)

class Solution {class PackageNode {ListNode node;Integer index;public PackageNode(ListNode node, Integer index) {this.node = node;this.index = index;}}public ListNode mergeKLists(ListNode[] lists) {if (lists.length == 0) {return null;}ListNode head = null;ListNode p = head;PriorityQueue<PackageNode> priorityQueue = new PriorityQueue<>(lists.length, Comparator.comparingInt(a -> a.node.val));for (int i = 0; i < lists.length; i++) {if (lists[i] != null) {priorityQueue.add(new PackageNode(lists[i], i));lists[i] = lists[i].next;}}while (priorityQueue.size() > 0) {PackageNode packageNode = priorityQueue.poll();Integer index = packageNode.index;if (lists[index] != null) {priorityQueue.add(new PackageNode(lists[index], index));lists[index] = lists[index].next;}if (head == null) {head = packageNode.node;p = head;} else {p.next = packageNode.node;p = p.next;}}return head;}
}

注意事项

对于全都遍历的,使用递归很方便

习题

判断两棵树是否相同

leetcode:相同的树

注意异或^的使用,只有一个成立时为真

对于全都遍历的,使用递归很方便!!!

class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {ArrayList<TreeNode> list1 = new ArrayList<>();ArrayList<TreeNode> list2 = new ArrayList<>();list1.add(p);list2.add(q);while (!list1.isEmpty() && !list2.isEmpty()) {p = list1.remove(0);q = list2.remove(0);if (p == null && q == null) {continue;} else if (p != null ^ q != null) {return false;}if (p.val != q.val) {return false;}if (p.left != null && q.left != null) {list1.add(p.left);list2.add(q.left);} else if (p.left == null ^ q.left == null) {return false;}if (p.right != null && q.right != null) {list1.add(p.right);list2.add(q.right);} else if (p.right == null ^ q.right == null) {return false;}}return list1.isEmpty() && list2.isEmpty();}
}

判断树是否是镜面树

leetcode:对称二叉树

虽然是简单,但是也做了不少时间

传两个头结点(left,right)!!!我又用了层序遍历

判断left.val == right.val && fun(left.left, right.right) && fun(left.right, right.left)

class Solution {public boolean isSymmetric(TreeNode root) {return isSymmetric(root, root);}public boolean isSymmetric(TreeNode p, TreeNode q) {if (p == null ^ q == null) {return false;}if (p == null && q == null) {return true;}return p.val == q.val && isSymmetric(p.left, q.right) && isSymmetric(p.right, q.left);}public boolean isSymmetricLevel(TreeNode root) {if (root == null) {return true;}ArrayList<TreeNode> treeList = new ArrayList<>();treeList.add(root);while (!treeList.isEmpty()) {if (treeList.size() > 1 && (treeList.size() & 1) != 0) {return false;}int len = treeList.size();for (int i = 0; i < len >> 1; i++) {int leftIndex = len - i - 1;if (treeList.get(i) == null ^ treeList.get(leftIndex) == null) {return false;}if (treeList.get(i) == null && treeList.get(leftIndex) == null) {continue;}if (treeList.get(i).val != treeList.get(leftIndex).val) {return false;}treeList.add(treeList.get(i).left);treeList.add(treeList.get(i).right);}for (int i = len >> 1; i < len; i++) {if (treeList.get(i) == null) {continue;}treeList.add(treeList.get(i).left);treeList.add(treeList.get(i).right);}for (int i = 0; i < len; i++) {treeList.remove(0);}}return true;}
}

返回树的最大深度

leetcode:二叉树的最大深度

用递归思想代码十分简单。差点又想用层序

class Solution {public int maxDepth(TreeNode root) {if (root == null) {return 0;}return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));}
}

先序遍历和中序遍历建树

leetcode:从前序与中序遍历序列构造二叉树

没啥说的,常见题

    class Solution {HashMap<Integer, Integer> numSite = new HashMap<>();public TreeNode buildTree(int[] preorder, int[] inorder) {if (preorder.length <= 0) {return null;}for (int i = 0; i < inorder.length; i++) {numSite.put(inorder[i], i);}return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}public TreeNode buildTree(int[] preorder, int preLow, int preHigh, int[] inorder, int inLow, int inHigh) {if (preLow > preHigh) {return null;}TreeNode head = new TreeNode(preorder[preLow]);if (preLow < preHigh) {int index = numSite.get(head.val);head.left = buildTree(preorder, preLow + 1, preLow + (index - inLow), inorder, inLow, index - 1);head.right = buildTree(preorder, preLow + (index - inLow) + 1, preHigh, inorder, index + 1, inHigh);}return head;}}


http://www.ppmy.cn/news/51041.html

相关文章

2023年天梯赛模拟赛

//能力有限&#xff0c;只展示一百分代码。前八个题一般是原题&#xff0c;所以不展示题目。 L1-1 嫑废话上代码 #include<bits/stdc.h> using namespace std; int main(){cout<<"Talk is cheap. Show me the code.";return 0; } L1-2 九牛一毛 这是…

python算法中的字符串算法(详解)

目录 学习目标: 学习内容: Ⅰ. 字符串匹配算法 ①. Brute-Force算法 ②. KMP算法

【Springboot系列】项目启动时怎么给mongo表加自动过期索引

1、前言 在之前操作mongo的过程中&#xff0c;都是自动创建&#xff0c;几乎没有手动创建过表。 这次开发中有张表数据量大&#xff0c;并且不是特别重要&#xff0c;数据表维护一个常见的问题是过期数据没有被及时清理&#xff0c;导致数据量过大&#xff0c;查询变得缓慢。…

ios客户端学习笔记(三):学习Swift的设计模式

设计模式是指在软件开发中常用的一些解决问题的方法和思想&#xff0c;它可以帮助你更好地组织代码和提高代码的可维护性。你需要学习常见的设计模式&#xff0c;如MVC、MVVM、单例模式、工厂模式等&#xff0c;在开发应用程序时应用它们。 当你学习常见的设计模式时&#xff…

线程常用方法

线程常用方法 setName() //设置线程名称&#xff0c;使之与参数name相同getName() //返回该线程的名称start() //使该线程开始执行&#xff1b;Java虚拟机底层调用该线程的start0方法run() //调用线程对象run方法&#xff1b;setPriority() //更改线程的优先级getPrio…

Utilities非默认目录构建和安装

在AppArmor零知识学习八、源码构建&#xff08;5&#xff09;中&#xff0c;详细介绍了Utilities的构建步骤&#xff0c;但那完全使用的是官网给出的默认参数。如果需要将目标文件生成到指定目录而非默认的/usr&#xff0c;则需要进行一些修改&#xff0c;本文就来详述如何进行…

gitee教程精简版

$ git config --global user.name "Your Name" $ git config --global user.email "emailexample.com" 设置名字和邮箱 初始化 git init git add test.txt 将文件预先添加到git仓库 git commit -m "刚刚我创建了一个文本"提交给git仓库&#x…

MySQL学习笔记第三天

第04章 运算符 1.算术运算符 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xff08;/&#xff09;和取模&a…