刷题笔记-树
刷题笔记-树
2021年4月8日
标签: 排序,链表排序, 归并排序
class Solution {
// 归并排序
public ListNode sortList(ListNode head) {
return sortList(head, null);
}
private ListNode sortList(ListNode head, ListNode tail){
if(head == null){
return head;
}
if(head.next == tail){
head.next = null;
return head;
}
ListNode slow = head, fast = head;
while(fast != tail){
slow = slow.next;
fast = fast.next;
if(fast != tail){
fast = fast.next;
}
}
ListNode mid = slow;
ListNode list1 = sortList(head, mid);
ListNode list2 = sortList(mid, tail);
return merge2(list1, list2);
}
public ListNode merge1(ListNode head1, ListNode head2) {
ListNode dummyHead = new ListNode(0);
ListNode temp = dummyHead, temp1 = head1, temp2 = head2;
while (temp1 != null && temp2 != null) {
if (temp1.val <= temp2.val) {
temp.next = temp1;
temp1 = temp1.next;
} else {
temp.next = temp2;
temp2 = temp2.next;
}
temp = temp.next;
}
if (temp1 != null) {
temp.next = temp1;
} else if (temp2 != null) {
temp.next = temp2;
}
return dummyHead.next;
}
private ListNode merge2(ListNode list1, ListNode list2){
if(list1 == null){
return list2;
}
if(list2 == null){
return list1;
}
if(list1.val > list2.val){
list2.next = merge2(list2.next, list1);
return list2;
}else{
list1.next = merge2(list1.next, list2);
return list1;
}
}
}
标签: 二叉树
class Solution {
public boolean isSymmetric(TreeNode root) {
return isSymmetric(root, root);
}
private boolean isSymmetric(TreeNode root1, TreeNode root2){
if(root1 == null && root2 == null){
return true;
}
if(root1 == null || root2 == null){
return false;
}
if(root1.val != root2.val){
return false;
}
return isSymmetric(root1.left, root2.right) && isSymmetric(root1.right, root2.left);
}
}
标签:二叉搜索树
方法一: 迭代(中序遍历)
class Solution {
public Node treeToDoublyList(Node root) {
// 迭代
if(root == null){
return root;
}
Node dummy = new Node();
Node cur = dummy;
Deque<Node> stack = new LinkedList<>();
while(root != null || !stack.isEmpty()){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
root.left = cur;
cur.right = root;
cur = cur.right;
root = root.right;
}
Node node = dummy.right;
node.left = cur;
cur.right = node;
return node;
}
}
方法二: 递归(中序遍历)
class Solution {
public Node dummy = new Node();
public Node cur = dummy;
public Node treeToDoublyList(Node root) {
if(root == null){
return root;
}
// 递归
inorderTraversal(root);
Node node = dummy.right;
node.left = cur;
cur.right = node;
return node;
}
private void inorderTraversal(Node root){
if(root == null){
return;
}
inorderTraversal(root.left);
cur.right = root;
root.left = cur;
cur = cur.right;
inorderTraversal(root.right);
}
}
标签: 深度搜索,回溯算法
方法一: DFS
class Solution {
List<String> res = new ArrayList<>();
public String[] permutation(String s) {
int len = s.length();
if (len == 0) {
return new String[0];
}
char[] charArray = s.toCharArray();
Arrays.sort(charArray);
StringBuilder path = new StringBuilder();
boolean[] used = new boolean[len];
dfs(charArray, path, used);
return res.toArray(new String[res.size()]);
}
private void dfs(char[] charArray, StringBuilder path, boolean[] used){
int len = charArray.length;
// 保存数据
if(len == path.length()){
res.add(path.toString());
return;
}
for(int i=0; i<len; i++){
if(!used[i]){
// 剪枝
if(i > 0 && charArray[i] == charArray[i-1] && !used[i-1]){
continue;
}
path.append(charArray[i]);
used[i] = true;
dfs(charArray, path, used);
path.deleteCharAt(path.length() - 1);
used[i] = false;
}
}
}
}
标签:广度优先搜索
2021年4月9日
方法二: 递归
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null){
return null;
}
TreeNode tmp = root.left;
root.left = mirrorTree(root.right);
root.right = mirrorTree(tmp);
return root;
}
}
方法一: 迭代
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null){
return root;
}
// 层序遍历迭代交换左右子树
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode node = queue.poll();
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
return root;
}
}
方法一:递归
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null){
return false;
}
if (root.left == null && root.right == null) {
return targetSum == root.val;
}
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}
}
方法二:BFS(迭代) 层序遍历
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
// BFS
if(root == null){
return false;
}
Queue<TreeNode> nodeQ = new LinkedList<>();
Queue<Integer> sumQ = new LinkedList<>();
nodeQ.offer(root);
sumQ.offer(root.val);
while (!nodeQ.isEmpty()){
TreeNode node = nodeQ.poll();
int sum = sumQ.poll();
if(node.left == null && node.right == null && sum == targetSum){
return true;
}
if(node.left != null){
nodeQ.offer(node.left);
sumQ.offer(sum + node.left.val);
}
if(node.right != null){
nodeQ.offer(node.right);
sumQ.offer(sum + node.right.val);
}
}
return false;
}
}
方法一: DFS
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
int sum = 0;
def(root, targetSum, sum);
return res;
}
private void dfs(TreeNode root, Integer targetSum, int sum) {
if(root == null){
return;
}
sum += root.val;
path.add(root.val);
if(root.left == null && root.right == null && sum == targetSum){
res.add(new ArrayList(path));
}
def(root.left, targetSum, sum);
def(root.right, targetSum, sum);
sum -= root.val;
path.remove(path.size()-1);
}
}
方法二: BFS
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> res = new ArrayList<>();
// BFS
if (root == null) {
return res;
}
Queue<TreeNode> nodeQ = new LinkedList<>();
Queue<List<Integer>> pathQ = new LinkedList<>();
Queue<Integer> sumQ = new LinkedList<>();
nodeQ.offer(root);
List<Integer> pathR = new ArrayList<Integer>();
pathR.add(root.val);
pathQ.offer(pathR);
sumQ.offer(root.val);
while (!nodeQ.isEmpty()) {
TreeNode node = nodeQ.poll();
List<Integer> path = pathQ.poll();
int sum = sumQ.poll();
if (node.left == null && node.right == null && sum == targetSum) {
res.add(path);
}
if (node.left != null) {
List<Integer> newList = new ArrayList<>(path);
newList.add(node.left.val);
nodeQ.offer(node.left);
pathQ.offer(newList);
sumQ.offer(sum + node.left.val);
}
if (node.right != null) {
List<Integer> newList = new ArrayList<>(path);
newList.add(node.right.val);
nodeQ.offer(node.right);
pathQ.offer(newList);
sumQ.offer(sum + node.right.val);
}
}
return res;
}
}
方法一: 双重递归(DFS + DFS)
class Solution {
public int pathSum(TreeNode root, int targetSum) {
if(root == null){
return 0;
}
int count = countPath(root, targetSum);
count += pathSum(root.left, targetSum);
count += pathSum(root.right, targetSum);
return count;
}
/**
* 递归计算以树为根节点的路径条数之合;
*/
private int countPath(TreeNode root, int sum){
if(root == null){
return 0;
}
int count = 0;
if(root.val == sum){
count ++;
}
count += countPath(root.left, sum - root.val);
count += countPath(root.right, sum - root.val);
return count;
}
}
方法一: DFS + 记忆
class Solution {
HashMap<Character, List<Integer>> map; // 用于存储ring里面字符的索引位置
String ring;
String key;
private int[][] memo;
public int findRotateSteps(String ring, String key) {
this.ring = ring;
this.key = key;
map = new HashMap<>();
int m = key.length();
int n = ring.length();
this.memo = new int[m][n];
for(int i = 0; i < ring.length(); i++){
Character r = ring.charAt(i);
List<Integer> list = map.getOrDefault(r, new ArrayList<Integer>());
list.add(i);
map.put(r, list);
}
return dfs(0, 0);
}
private int dfs(int ringI, int keyI){
if(keyI == key.length()){
return 0;
}
if(memo[keyI][ringI] != 0){
return memo[keyI][ringI];
}
List<Integer> list = map.get(key.charAt(keyI));
int res = Integer.MAX_VALUE;
for(Integer index : list){
// 计算当前ring到目标key的最小步骤
int minCur = Math.min(Math.abs(ringI - index),ring.length() - Math.abs(ringI - index));
// 计算下一key到需要的最小步骤
int minNext = dfs(index, keyI+1);
res = Math.min(res, minCur + minNext);
}
memo[keyI][ringI] = res + 1;
return res + 1;
}
}
2021年4月10日
方法一: 堆排序
class Solution {
public int[] sortArray(int[] nums) {
// 堆排序
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>((o1, o2) -> o1 - o2);
for(int num : nums){
minHeap.offer(num);
}
int i = 0;
while(!minHeap.isEmpty()){
nums[i++] = minHeap.poll();
}
return nums;
}
}
方法二: 快排
class Solution {
int[] nums;
public int[] sortArray(int[] nums) {
// 快排
this.nums = nums;
quickSort(0, nums.length);
return nums;
}
private void quickSort(int begin, int end){
if(end - begin < 2){
return;
}
// 获取轴点位置
int pivot = pivotIndex(begin, end);
// 递归
quickSort(begin, pivot);
quickSort(pivot + 1, end);
}
private int pivotIndex(int begin, int end){
swap(begin, begin + (int)(Math.random() * (end - begin)));
int pivot = nums[begin];
end--;
while(begin < end){
while(begin < end){
if(pivot < nums[end]){
end--;
}else{
nums[begin++] = nums[end];
break;
}
}
while(begin < end){
if(pivot > nums[begin]){
begin++;
}else{
nums[end--] = nums[begin];
break;
}
}
}
nums[begin] = pivot;
return begin;
}
private void swap(int index1, int index2){
int tmp = nums[index1];
nums[index1] = nums[index2];
nums[index2] = tmp;
}
}
class Solution {
int n;
int k;
List<Integer> list;
public int[] numsSameConsecDiff(int n, int k) {
this.n = n;
this.k = k;
this.list = new ArrayList<>();
if(n == 1){
return new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
}
for(int i = 1; i <= 9; i++){
dfs(i);
}
int[] res = new int[list.size()];
int i = 0;
for(int r : list){
res[i++] = r;
}
return res;
}
private void dfs(int digit){
if((int)(Math.log10(digit)) + 1 == n){
list.add(digit);
return;
}
int pre = digit % 10; // 数字末位
if(pre >= k){
dfs(10 * digit + pre - k); // 后一位追加上次末位左边
}
if(k != 0 && pre + k <= 9){
dfs(10 * digit + pre + k); // 后一位追加上次末位右边
}
}
}
2021年4月11日
方法一: 迭代反向中序遍历(从大到小排)
class Solution {
public int kthLargest(TreeNode root, int k) {
if(root == null){
return 0;
}
Deque<TreeNode> stack = new LinkedList<>();
while(root != null || !stack.isEmpty()){
while(root != null){
stack.push(root);
root = root.right;
}
root = stack.pop();
if(--k == 0){
return root.val;
}
root = root.left;
}
return 0;
}
}
方法二: 递归反向中序遍历(从大到小排)
class Solution {
int k;
int ans = -1;
public int kthLargest(TreeNode root, int k) {
this.k = k;
if(root == null){
return ans;
}
inorderTraversal(root);
return ans;
}
private void inorderTraversal(TreeNode root){
if(root == null){
return;
}
inorderTraversal(root.right);
if(--k == 0){
ans = root.val;
return;
}
inorderTraversal(root.left);
}
}
方法一: BFS
/**
* BFS(层序遍历)
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if(root == null){
return "";
}
StringBuilder res = new StringBuilder();
res.append("[");
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode node = queue.poll();
if (node != null){
res.append(node.val);
res.append(",");
queue.offer(node.left);
queue.offer(node.right);
}else{
res.append("null");
res.append(",");
}
}
res.deleteCharAt(res.length() -1);
res.append("]");
return res.toString();
}
public TreeNode deserialize(String data) {
if (data.equals("")){
return null;
}
String[] nodeList = data.substring(1, data.length() - 1).split(",");
TreeNode root = new TreeNode(Integer.parseInt(nodeList[0]));
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int index = 1;
while (!queue.isEmpty()){
TreeNode tree = queue.poll();
if (!nodeList[index].equals("null")){
tree.left = new TreeNode(Integer.parseInt(nodeList[index]));
queue.offer(tree.left);
}
index++;
if (!nodeList[index].equals("null")){
tree.right = new TreeNode(Integer.parseInt(nodeList[index]));
queue.offer(tree.right);
}
index++;
}
return root;
}
}
2021年4月12日
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A == null || B == null){
return false;
}
return help(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
private boolean help(TreeNode tree1, TreeNode tree2){
if(tree2 == null){
return true;
}
if(tree1 == null || tree1.val != tree2.val){
return false;
}
return help(tree1.left, tree2.left) && help(tree1.right, tree2.right);
}
}
class Solution {
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}
}
2021年4月13日
方法一: 迭代(中序遍历)
class Solution {
public boolean isValidBST(TreeNode root) {
long min = Long.MIN_VALUE;
if(root == null){
return true;
}
Deque<TreeNode> stack = new LinkedList<>();
while(root != null || !stack.isEmpty()){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
if(root.val <= min){
return false;
}
min = root.val;
root = root.right;
}
return true;
}
}
方法二:递归(中序遍历)
class Solution {
long min = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
if(root == null){
return true;
}
if (!isValidBST(root.left)){
return false;
}
if(root.val <= min){
return false;
}
min = root.val;
if (!isValidBST(root.right)){
return false;
}
return true;
}
}
方法三:递归
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
private boolean isValidBST(TreeNode node, long lowL, long upL){
if (node == null) {
return true;
}
if (node.val <= lowL || node.val >= upL) {
return false;
}
return isValidBST(node.left, lowL, node.val) && isValidBST(node.right, node.val, upL);
}
}
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null){
return res;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> list = new ArrayList<Integer>();
int queueSize = queue.size();
for(; queueSize>0; queueSize--){
TreeNode node = queue.poll();
list.add(node.val);
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
res.add(list);
}
return res;
}
}
2021年4月14日份
方法一: 层序遍历,维护队列保存上层节点
class Solution {
public TreeNode addOneRow(TreeNode root, int val, int depth) {
// 层序遍历
if(depth == 1){
return new TreeNode(val, root, null);
}
int level = 1;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty() && level < depth -1){
int size = queue.size();
level++;
for(; size > 0; size--){
TreeNode node = queue.poll();
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
}
while(!queue.isEmpty()){
TreeNode node = queue.poll();
node.left = new TreeNode(val, node.left, null);
node.right = new TreeNode(val, null, node.right);
}
return root;
}
}
方法一 : 层序遍历取每一层最右边的数
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = new ArrayList();
// 层序遍历取每一层最右边的数
if(root == null){
return res;
}
List<List<Integer>> levelList = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> tmp = new ArrayList<>();
int size = queue.size();
for(; size > 0; size--){
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
levelList.add(new ArrayList(tmp));
}
for(List<Integer> list : levelList){
res.add(list.get(list.size() - 1 ));
}
return res;
}
}
方法一: DFS(给每个节点添加上父节点) + BFS (层次遍历周围节点)
class Solution {
Map<TreeNode, TreeNode> parentMap;
Set<TreeNode> visited;
List<Integer> res = new ArrayList<>();
public List<Integer> distanceK(TreeNode root, TreeNode target, int K) {
if(root == null){
return res;
}
parentMap = new HashMap();
addParent(null, root);
visited = new HashSet<>();
visited.add(target);
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(target);
while (!queue.isEmpty() && K > 0) {
int size = queue.size();
K--;
for (; size > 0; size--) {
TreeNode node = queue.poll();
visited.add(node);
TreeNode parent = parentMap.get(node);
if (parent != null && !visited.contains(parent)) {
queue.offer(parent);
}
if (node.left != null && !visited.contains(node.left)) {
queue.offer(node.left);
}
if (node.right != null && !visited.contains(node.right)) {
queue.offer(node.right);
}
}
}
while (!queue.isEmpty()) {
res.add(queue.poll().val);
}
return res;
}
private void addParent(TreeNode parent, TreeNode node){
if(node != null){
parentMap.put(node, parent);
addParent(node, node.left);
addParent(node, node.right);
}
}
}
2021年4月15日份
方法一: 每次选取中间的节点作为根节点
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return addNode(nums, 0, nums.length);
}
private TreeNode addNode(int[] nums, int left, int right){
if(left >= right){
return null;
}
int mid = left + right >> 1;
TreeNode root = new TreeNode(nums[mid]);
root.left = addNode(nums, left, mid);
root.right = addNode(nums, mid+1, right);
return root;
}
}
方法一: 迭代(层序遍历,每层左边节点next指向的该层右边节点,最后一个节点直接指向null)
class Solution {
public Node connect(Node root) {
if(root == null){
return root;
}
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
int sizeL;
while(!queue.isEmpty()){
sizeL = queue.size();
for(; sizeL > 0; sizeL --){
Node node = queue.poll();
if(sizeL == 1){
node.next = null;
}else{
node.next = queue.peek();
}
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
}
return root;
}
}
方法二: 利用上层已经构建的next
class Solution {
public Node connect(Node root) {
if (root == null) {
return root;
}
root.next = null;
Node leftNode = root;
while (leftNode.left != null) {
Node head = leftNode;
while (head != null) {
head.left.next = head.right;
if (head.next != null) {
head.right.next = head.next.left;
}
head = head.next;
}
leftNode = leftNode.left;
}
return root;
}
}
2021年4月16日份
方法一:遍历获取每一个节点左右子树的最大深度,并且在遍历过程中维护更新最大直径
class Solution {
int max = 0;
public int diameterOfBinaryTree(TreeNode root) {
if(root == null){
return max;
}
help(root);
return max;
}
// 遍历获取每一个节点左右子树的最大深度,并且在遍历过程中维护更新最大直径
private int help(TreeNode node){
if(node == null){
return 0;
}
int leftDepth = help(node.left);
int rightDepth = help(node.right);
max = Math.max(max, leftDepth + rightDepth);
return Math.max(leftDepth, rightDepth) + 1;
}
}
方法一: 同二叉树层序遍历(迭代)
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null){
return res;
}
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
int sizeLeve;
while(!queue.isEmpty()){
sizeLeve = queue.size();
List<Integer> nodeList = new ArrayList<>();
for(; sizeLeve > 0; sizeLeve--){
Node node = queue.poll();
nodeList.add(node.val);
List<Node> children = node.children;
for( Node child : children){
queue.offer(child);
}
}
res.add(new ArrayList<Integer>(nodeList));
}
return res;
} Leetcode - Leetcode - Leetcode -
}
方法: 遍历把每个数字作为根节点,生成左右的子树集合,再拼接左右子树
class Solution {
public List<TreeNode> generateTrees(int n) {
if(n == 0){
return new LinkedList<TreeNode>();
}
return generateTrees(1, n);
}
private List<TreeNode> generateTrees(int l, int r){
List<TreeNode> allTrees = new LinkedList<TreeNode>();
if (l > r) {
allTrees.add(null);
return allTrees;
}
for(int i = l; i <= r; i++){
List<TreeNode> leftNodes = generateTrees(l, i-1);
List<TreeNode> rightNodes = generateTrees(i+1, r);
// 遍历拼接左右节点
for(TreeNode left : leftNodes){
for(TreeNode right : rightNodes){
allTrees.add(new TreeNode(i, left, right));
}
}
}
return allTrees;
}
}
2021年4月19日份
方法:遍历获取每一个节点,就算左右子树最长同值路径,并且在遍历过程中维护更新整棵树的最大直径(类似题Leetcode543)
class Solution {
int max = 0;
public int longestUnivaluePath(TreeNode root) {
if(root == null){
return max;
}
help(root);
return max;
}
// 遍历获取每一个节点,就算左右子树最长同值路径,并且在遍历过程中维护更新整棵树的最大直径
private int help(TreeNode node){
if(node == null){
return 0;
}
int left = help(node.left);
int right = help(node.right);
int leftMax = 0, rightMax = 0;
if(node.left != null && node.left.val == node.val){
leftMax = left + 1;
}
if(node.right != null && node.right.val == node.val){
rightMax = right + 1;
}
max = Math.max(max, leftMax + rightMax);
return Math.max(leftMax, rightMax);
}
}
方法一: 递归
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || root == p || root == q){
return root;
}
// 左右子树寻找p、q子树
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.left, p, q);
// 左右子树各包含p、q返回该根节点
if(left != null && right != null){
return root;
}
// 全部在左边,返回作子树
if(left != null && right == null){
return left;
}
return right;
}
}
方法二: 利用HashMap储存父节点
class Solution {
Map<Integer, TreeNode> parent = new HashMap<Integer, TreeNode>();
Set<Integer> visited = new HashSet<Integer>();
public void addParent(TreeNode root) {
if (root.left != null) {
parent.put(root.left.val, root);
addParent(root.left);
}
if (root.right != null) {
parent.put(root.right.val, root);
addParent(root.right);
}
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
addParent(root);
while (p != null) {
visited.add(p.val);
p = parent.get(p.val);
}
while (q != null) {
if (visited.contains(q.val)) {
return q;
}
q = parent.get(q.val);
}
return null;
}
}
2021年4月20日份
方法:层序遍历(在存储数据做处理)
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null){
return res;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean leftArrave = true;
int levelSize;
while(!queue.isEmpty()){
levelSize = queue.size();
Deque<Integer> levelList = new LinkedList<Integer>();
for(; levelSize > 0; levelSize--){
TreeNode node = queue.poll();
if(leftArrave){
levelList.offerLast(node.val);
}else{
levelList.offerFirst(node.val);
}
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
leftArrave = !leftArrave;
res.add(new ArrayList<Integer>(levelList));
}
return res;
}
}
class Solution {
public int countNodes(TreeNode root) {
if(root == null){
return 0;
}
int left = countLevel(root.left);
int right = countLevel(root.right);
if(left == right){
return countNodes(root.right) + (1<<left);
}else{
return countNodes(root.left) + (1<<right);
}
}
private int countLevel(TreeNode root){
int level = 0;
while(root != null){
level++;
root = root.left;
}
return level;
}
}
2021年4月21日份
class Solution {
int min = Integer.MAX_VALUE;
int pre = -100000000;
public int getMinimumDifference(TreeNode root) {
if(root == null){
return min;
}
help(root);
return min;
}
private void help(TreeNode root){
if(root == null){
return;
}
help(root.left);
min = Math.min(min,root.val - pre);
pre = root.val;
help(root.right);
}
}
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
int sum = 0;
def(root, targetSum);
return res;
}
private void def(TreeNode root, int sum) {
if(root == null){
return;
}
path.add(root.val);
sum -= root.val;
if(root.left == null && root.right == null && sum == 0){
res.add(new ArrayList<Integer>(path));
}
def(root.left, sum);
def(root.right, sum);
path.remove(path.size()-1);
}
}
2021年4月22日份
方法 : 层序遍历
class Solution {
public boolean isCompleteTree(TreeNode root) {
if(root == null){
return true;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean falg = false;
while(!queue.isEmpty()){
TreeNode node = queue.poll();
if(node == null){
falg = true;
continue;
}
if(falg){
return false;
}
queue.offer(node.left);
queue.offer(node.right);
}
return true;
}
Leetcode - Leetcode - Leetcode - Leetcode - }
方法一: 从右到左的层序遍历
class Solution {
int res;
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode node = queue.poll();
res = node.val;
if(node.right != null){
queue.offer(node.right);
}
if(node.left != null){
queue.offer(node.left);
}
}
return res;
}
}
2021年4月23日份
方法一: 双重递归
class Solution {
public int findTilt(TreeNode root) {
if(root == null){
return 0;
}
int podu = Math.abs(getTreeNodeSum(root.left) - getTreeNodeSum(root.right));
return podu + findTilt(root.left) + findTilt(root.right);
}
private int getTreeNodeSum(TreeNode root){
if(root == null){
return 0;
}
return root.val + getTreeNodeSum(root.left) + getTreeNodeSum(root.right);
}
}
方法二: dfs更新总结点坡度
class Solution {
int poduSum = 0;
public int findTilt(TreeNode root) {
dfs(root);
return poduSum;
}
private int dfs(TreeNode root){
if(root == null){
return 0;
}
int left = dfs(root.left);
int right = dfs(root.right);
poduSum += Math.abs(left - right);
return left + right + root.val;
}
}
方法一: 中序遍历 + 双指针
class Solution {
List<Integer> list;
public boolean findTarget(TreeNode root, int k) {
if(root == null){
return false;
}
list = new ArrayList<>();
inorderTraversal(root);
int l = 0;
int r = list.size() - 1;
int tmp;
while(l < r){
tmp = list.get(l) + list.get(r);
if(tmp == k){
return true;
}
if(tmp < k){
l++;
}else{
r--;
}
}
return false;
}
private void inorderTraversal(TreeNode root){
if(root == null){
return;
}
inorderTraversal(root.left);
list.add(root.val);
inorderTraversal(root.right);
}
}
方法二: HashSet + 任意遍历
class Solution {
Set < Integer > set = new HashSet();
public boolean findTarget(TreeNode root, int k) {
if(root == null){
return false;
}
if(set.contains(k - root.val)){
return true;
}
set.add(root.val);
if(findTarget(root.left, k)){
return true;
}
if(findTarget(root.right, k)){
return true;
}
return false;
}
}
方法: 简单递归即可
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1 == null){
return root2;
}
if(root2 == null){
return root1;
}
root1.left = mergeTrees(root1.left, root2.left);
root1.right = mergeTrees(root1.right, root2.right);
root1.val += root2.val;
return root1;
}
}
class Solution {
public String tree2str(TreeNode t) {
if(t==null)
return "";
if(t.left==null && t.right==null)
return t.val+"";
if(t.right==null)
return t.val+"("+tree2str(t.left)+")";
return t.val+"("+tree2str(t.left)+")("+tree2str(t.right)+")";
}
}