4.1节点间通路
错误在于return的是第一个末尾为4的节点。所以还是要用dfs或bfs
下面用BFS:
class Solution {
public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
Map<Integer,List<Integer>> map=new HashMap<>();
for(int[] p:graph){
if(!map.containsKey(p[0])){
map.put(p[0],new ArrayList<>());
}
map.get(p[0]).add(p[1]);
}
Queue<Integer> queue=new LinkedList<>();
queue.add(start);
//BFS
while(!queue.isEmpty()){
int size=queue.size();
while(size-- >0){
int st=queue.poll();
List<Integer>list=map.get(st);
if(list == null) continue;
for(int num:list){
if(num == target) return true;
queue.add(num);
}
map.put(st,null);
}
}
return false;
}
}
4.2最小高度树
一个简单的递归就好,pass
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
TreeNode node=helper(nums,0,nums.length-1);
return node;
}
TreeNode helper(int[] nums,int L,int R){
if(L>R) return null;
// if(L==R) return new TreeNode(nums[L]);
TreeNode ans=new TreeNode(nums[(L+R)/2]);
ans.left=helper(nums,L,(L+R)/2 -1);
ans.right=helper(nums,(L+R)/2+1,R);
return ans;
}
}
4.3特定深度节点链表
一个简单的BFS
class Solution {
public ListNode[] listOfDepth(TreeNode tree) {
if (tree == null) {
return new ListNode[0];
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(tree);
List<ListNode> list = new ArrayList<>();
ListNode dummyHead = new ListNode(-1);
while (!queue.isEmpty()) {
ListNode cur = dummyHead;
int size = queue.size();
for (int i = 0; i < size; i++) {
tree = queue.poll();
cur.next = new ListNode(tree.val);
cur = cur.next;
if (tree.left != null) {
queue.offer(tree.left);
}
if (tree.right != null) {
queue.offer(tree.right);
}
}
list.add(dummyHead.next);
}
ListNode[] res = new ListNode[list.size()];
for (int i = 0; i < list.size(); i++) {
res[i] = list.get(i);
}
return res;
}
}
4.4检查平衡性
一个简单的用递归去求树的高度,pass
class Solution {
private boolean flag=true;
public boolean isBalanced(TreeNode root) {
if(root==null) return true;
dfs(root);
return flag;
}
public int dfs(TreeNode root){
if(root==null) return 0;
int leftHigh=dfs(root.left);
int rightHigh=dfs(root.right);
if(Math.abs(leftHigh-rightHigh)>1){
flag=false;
}
return Math.max(leftHigh,rightHigh)+1;
}
}
4.5验证二叉搜索树
一个简单的中序遍历,pass,数据结构期末的考题
class Solution {
public boolean isValidBST(TreeNode root) {
//中序遍历
ArrayList<Integer>ans=new ArrayList<>();
Inorder(root,ans);
for(int i=1;i<ans.size();i++){
if(ans.get(i)<=ans.get(i-1)){
return false;
}
}
return true;
}
public void Inorder(TreeNode root,ArrayList<Integer>ans){
if(root==null) return;
Inorder(root.left,ans);
ans.add(root.val);
Inorder(root.right,ans);
}
}
4.6后继者
思路他写的比较清晰,但是我感觉下一次写不出来。危
class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
if (root == null) {
return null;
}
// 当前节点值小于等于目标值,那么当前目标值的后继者必然在右子树
if (p.val >= root.val) {
return inorderSuccessor(root.right, p);
}
// 否则结果有可能是当前节点,或者在当前节点的左子树中
// 那么先去左子树找一下试试,找不到的话返回当前节点即是结果
TreeNode node = inorderSuccessor(root.left, p);
return node == null ? root : node;
}
}
4.8首个共同祖先
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null || root==p || root==q) return root;
TreeNode rootLeft=lowestCommonAncestor(root.left,p,q);
TreeNode rootRight=lowestCommonAncestor(root.right,p,q);
if(rootLeft!=null && rootRight!=null) return root;
return rootLeft==null ? rootRight:rootLeft;
}
}
递归的一个写法。关键在于左右都不为空的时候是根节点。
但卡住我的是最后一行。
4.9二叉搜索树序列(※)
class Solution {
private List<List<Integer>> ans;
public List<List<Integer>> BSTSequences(TreeNode root) {
ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
// 如果 root==null 返回 [[]]
if (root == null) {
ans.add(path);
return ans;
}
List<TreeNode> queue = new LinkedList<>();
queue.add(root);
// 开始进行回溯
bfs(queue, path);
return ans;
}
private void bfs(List<TreeNode> queue,List<Integer>path){
if(queue.isEmpty()){
ans.add(new ArrayList<>(path));
return ;
}
List<TreeNode> copy = new ArrayList<>(queue);
for(int i=0;i<queue.size();i++){
TreeNode cur = queue.get(i);
path.add(cur.val);
queue.remove(i);
// 将左右子节点加入队列
if (cur.left != null) queue.add(cur.left);
if (cur.right != null) queue.add(cur.right);
bfs(queue, path);
// 恢复 path 和 queue ,进行回溯
path.remove(path.size() - 1);
//因为下面一行,queue.size()保持不变。
queue = new ArrayList<>(copy);
}
}
}
对BFS进行了魔改
比如[2,1,3],取出2以后要把1,3放进去。
然后按照正常流程是先1后3.但是队列里的1和3都应该有优先处置权。
这时就要用回溯。
复制了一份copy,可以保证queue.size()大小不变。
4.10检查子树
class Solution {
public boolean checkSubTree(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null)
return true;
if (t1 == null || t2 == null)
return false;
return helper(t1, t2) || checkSubTree(t1.left, t2) || checkSubTree(t1.right, t2);
}
public boolean helper(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null)
return true;
if (t1 == null || t2 == null)
return false;
return t1.val == t2.val && helper(t1.left, t2.left) && helper(t1.right, t2.right);
}
}
helper函数用来确定t1和t2一样的。
两层递归
4.12求和路径(❤)
用到的是前缀和。
代码及解析