4.236.给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 1:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
/**
* @author mys
* @version 2019.8.20
* 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
* 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,
* 满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
*
* 示例 1:
* 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
* 输出: 3
* 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
*/
package com.mys;
import org.junit.Test;
public class lowestCommonAncestor236 {
//LCA问题 二叉树的最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//二叉树为空
if (root == null) {
return root;
}
//指定节点为根节点,公共祖先为根节点
if (root == p || root == q) {
return root;
}
//在左子树和右子树分别查找是否包含指定节点p q
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left != null && right != null) {
return root;
} else if (left != null) {
return left;
} else if (right != null) {
return right;
}
return null;
}
@Test
public void fun() {
//创建二叉树
TreeNode root = new TreeNode(3);
TreeNode node1 = new TreeNode(5);
root.left = node1;
TreeNode node2 = new TreeNode(1);
root.right = node2;
TreeNode node3 = new TreeNode(6);
node1.left = node3;
TreeNode node4 = new TreeNode(2);
node1.right = node4;
TreeNode node5 = new TreeNode(0);
node2.left = node5;
TreeNode node6 = new TreeNode(8);
node2.right = node6;
TreeNode node7 = new TreeNode(7);
node4.left = node7;
TreeNode node8 = new TreeNode(4);
node4.right = node8;
TreeNode res = lowestCommonAncestor(root, node1, node2);
System.out.println(res.val);//3
TreeNode res1 = lowestCommonAncestor(root, node7, node8);
System.out.println(res1.val);//2
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
5.237.请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。
现有一个链表 – head = [4,5,1,9],它可以表示为:
示例 1:
输入: head = [4,5,1,9], node = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
说明:
链表至少包含两个节点。
链表中所有节点的值都是唯一的。
给定的节点为非末尾节点并且一定是链表中的一个有效节点。
不要从你的函数中返回任何结果。
/**
* @author mys
* @version 2019.8.20
* 请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。
*
* 输入: head = [4,5,1,9], node = 5
* 输出: [4,1,9]
* 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
*
* 说明:
* 链表至少包含两个节点。
* 链表中所有节点的值都是唯一的。
* 给定的节点为非末尾节点并且一定是链表中的一个有效节点。
* 不要从你的函数中返回任何结果。
*/
package com.mys;
import org.junit.Test;
public class DeleteNode237 {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
@Test
public void fun() {
//初始化节点
ListNode node1 = new ListNode(4, null);
ListNode node2 = new ListNode(5, null);
ListNode node3 = new ListNode(1, null);
ListNode node4 = new ListNode(9, null);
node1.next = node2;
node2.next = node3;
node3.next = node4;
//删除节点
deleteNode(node1);
//打印链表
ListNode head = new ListNode();
head.next = node1;
while (head.next != null) {
System.out.println(head.next.val);//5 1 9
head = head.next;
}
}
}
6.238.给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
示例:
输入: [1,2,3,4]
输出: [24,12,8,6]
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
/**
* @author mys
* @version 2019.8.20
* 给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,
* 其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
*
* 示例:
* 输入: [1,2,3,4]
* 输出: [24,12,8,6]
* 说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题
*/
package com.mys;
import org.junit.Test;
public class ProduceExceptSelf238 {
/**
* 时间复杂度:O(n)
*/
public int[] produceExceptSelf(int[] nums) {
int left = 1;//从左边累积
int right = 1;//从右边累积
//初始化数组
int[] res = new int[nums.length];
for (int i = 0; i < nums.length; i ++) {
res[i] = 1;
}
for (int i = 0; i < nums.length; i ++) {
//左边乘积
res[i] *= left;
left *= nums[i];
//右边乘积
res[nums.length - 1 - i] *= right;
right *= nums[nums.length - 1 - i];
}
return res;
}
@Test
public void fun() {
int[] nums = {1, 2, 3, 4};
int[] sum1 =produceExceptSelf3(nums);
for (int i = 0; i < nums.length; i ++) {
System.out.print(sum1[i] + " "); //24 12 8 6
}
}
}