基础新手
链表
注意事项
注意保存上下文环境。注意gc,不要有垃圾变量。换头结点注意考虑头
对于链表不要在乎是O(n)还是O(2n)
长短链表互换
习题
K个节点的组内逆序调整 ?
找n函数
逆转函数
第一组是否找齐
之后每组处理:start先指向下一组头,遍历完再指向尾
不在于算法,而在于coding能力
链表相加
注意长短链表互换,链表1结点+链表2结点+进位,注意最后进位需要补结点
阶段1:两个相加+进位 while(shortNode != null)
阶段2:单个链表+进位 while(longNode != null)
阶段3:链表结束,仍有进位,补结点 if(carry != 0)
上面三个阶段分别是3个循环
有序链表合并
注意换头,有一个为空就出循环
合并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; } }
树
注意事项
对于全都遍历的,使用递归很方便
习题
判断两棵树是否相同
注意异或^的使用,只有一个成立时为真
对于全都遍历的,使用递归很方便!!!
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(); } }
虽然是简单,但是也做了不少时间
传两个头结点(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; } }
返回树的最大深度
用递归思想代码十分简单。差点又想用层序
class Solution { public int maxDepth(TreeNode root) { if (root == null) { return 0; } return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); } }
先序遍历和中序遍历建树
没啥说的,常见题
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; } }