comments | difficulty | edit_url | rating | source | tags | ||||
---|---|---|---|---|---|---|---|---|---|
true |
中等 |
1804 |
第 270 场周赛 Q3 |
|
给你一棵 二叉树 的根节点 root
,这棵二叉树总共有 n
个节点。每个节点的值为 1
到 n
中的一个整数,且互不相同。给你一个整数 startValue
,表示起点节点 s
的值,和另一个不同的整数 destValue
,表示终点节点 t
的值。
请找到从节点 s
到节点 t
的 最短路径 ,并以字符串的形式返回每一步的方向。每一步用 大写 字母 'L'
,'R'
和 'U'
分别表示一种方向:
'L'
表示从一个节点前往它的 左孩子 节点。'R'
表示从一个节点前往它的 右孩子 节点。'U'
表示从一个节点前往它的 父 节点。
请你返回从 s
到 t
最短路径 每一步的方向。
示例 1:
输入:root = [5,1,2,3,null,6,4], startValue = 3, destValue = 6 输出:"UURL" 解释:最短路径为:3 → 1 → 5 → 2 → 6 。
示例 2:
输入:root = [2,1], startValue = 2, destValue = 1 输出:"L" 解释:最短路径为:2 → 1 。
提示:
- 树中节点数目为
n
。 2 <= n <= 105
1 <= Node.val <= n
- 树中所有节点的值 互不相同 。
1 <= startValue, destValue <= n
startValue != destValue
我们可以先找到节点
时间复杂度
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def getDirections(
self, root: Optional[TreeNode], startValue: int, destValue: int
) -> str:
def lca(node: Optional[TreeNode], p: int, q: int):
if node is None or node.val in (p, q):
return node
left = lca(node.left, p, q)
right = lca(node.right, p, q)
if left and right:
return node
return left or right
def dfs(node: Optional[TreeNode], x: int, path: List[str]):
if node is None:
return False
if node.val == x:
return True
path.append("L")
if dfs(node.left, x, path):
return True
path[-1] = "R"
if dfs(node.right, x, path):
return True
path.pop()
return False
node = lca(root, startValue, destValue)
path_to_start = []
path_to_dest = []
dfs(node, startValue, path_to_start)
dfs(node, destValue, path_to_dest)
return "U" * len(path_to_start) + "".join(path_to_dest)
class Solution {
public String getDirections(TreeNode root, int startValue, int destValue) {
TreeNode node = lca(root, startValue, destValue);
StringBuilder pathToStart = new StringBuilder();
StringBuilder pathToDest = new StringBuilder();
dfs(node, startValue, pathToStart);
dfs(node, destValue, pathToDest);
return "U".repeat(pathToStart.length()) + pathToDest.toString();
}
private TreeNode lca(TreeNode node, int p, int q) {
if (node == null || node.val == p || node.val == q) {
return node;
}
TreeNode left = lca(node.left, p, q);
TreeNode right = lca(node.right, p, q);
if (left != null && right != null) {
return node;
}
return left != null ? left : right;
}
private boolean dfs(TreeNode node, int x, StringBuilder path) {
if (node == null) {
return false;
}
if (node.val == x) {
return true;
}
path.append('L');
if (dfs(node.left, x, path)) {
return true;
}
path.setCharAt(path.length() - 1, 'R');
if (dfs(node.right, x, path)) {
return true;
}
path.deleteCharAt(path.length() - 1);
return false;
}
}
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
string getDirections(TreeNode* root, int startValue, int destValue) {
TreeNode* node = lca(root, startValue, destValue);
string pathToStart, pathToDest;
dfs(node, startValue, pathToStart);
dfs(node, destValue, pathToDest);
return string(pathToStart.size(), 'U') + pathToDest;
}
private:
TreeNode* lca(TreeNode* node, int p, int q) {
if (node == nullptr || node->val == p || node->val == q) {
return node;
}
TreeNode* left = lca(node->left, p, q);
TreeNode* right = lca(node->right, p, q);
if (left != nullptr && right != nullptr) {
return node;
}
return left != nullptr ? left : right;
}
bool dfs(TreeNode* node, int x, string& path) {
if (node == nullptr) {
return false;
}
if (node->val == x) {
return true;
}
path.push_back('L');
if (dfs(node->left, x, path)) {
return true;
}
path.back() = 'R';
if (dfs(node->right, x, path)) {
return true;
}
path.pop_back();
return false;
}
};
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func getDirections(root *TreeNode, startValue int, destValue int) string {
var lca func(node *TreeNode, p, q int) *TreeNode
lca = func(node *TreeNode, p, q int) *TreeNode {
if node == nil || node.Val == p || node.Val == q {
return node
}
left := lca(node.Left, p, q)
right := lca(node.Right, p, q)
if left != nil && right != nil {
return node
}
if left != nil {
return left
}
return right
}
var dfs func(node *TreeNode, x int, path *[]byte) bool
dfs = func(node *TreeNode, x int, path *[]byte) bool {
if node == nil {
return false
}
if node.Val == x {
return true
}
*path = append(*path, 'L')
if dfs(node.Left, x, path) {
return true
}
(*path)[len(*path)-1] = 'R'
if dfs(node.Right, x, path) {
return true
}
*path = (*path)[:len(*path)-1]
return false
}
node := lca(root, startValue, destValue)
pathToStart := []byte{}
pathToDest := []byte{}
dfs(node, startValue, &pathToStart)
dfs(node, destValue, &pathToDest)
return string(bytes.Repeat([]byte{'U'}, len(pathToStart))) + string(pathToDest)
}
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function getDirections(root: TreeNode | null, startValue: number, destValue: number): string {
const lca = (node: TreeNode | null, p: number, q: number): TreeNode | null => {
if (node === null || [p, q].includes(node.val)) {
return node;
}
const left = lca(node.left, p, q);
const right = lca(node.right, p, q);
return left && right ? node : left ?? right;
};
const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => {
if (node === null) {
return false;
}
if (node.val === x) {
return true;
}
path.push('L');
if (dfs(node.left, x, path)) {
return true;
}
path[path.length - 1] = 'R';
if (dfs(node.right, x, path)) {
return true;
}
path.pop();
return false;
};
const node = lca(root, startValue, destValue);
const pathToStart: string[] = [];
const pathToDest: string[] = [];
dfs(node, startValue, pathToStart);
dfs(node, destValue, pathToDest);
return 'U'.repeat(pathToStart.length) + pathToDest.join('');
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} startValue
* @param {number} destValue
* @return {string}
*/
var getDirections = function (root, startValue, destValue) {
const lca = (node, p, q) => {
if (node === null || [p, q].includes(node.val)) {
return node;
}
const left = lca(node.left, p, q);
const right = lca(node.right, p, q);
return left && right ? node : left ?? right;
};
const dfs = (node, x, path) => {
if (node === null) {
return false;
}
if (node.val === x) {
return true;
}
path.push('L');
if (dfs(node.left, x, path)) {
return true;
}
path[path.length - 1] = 'R';
if (dfs(node.right, x, path)) {
return true;
}
path.pop();
return false;
};
const node = lca(root, startValue, destValue);
const pathToStart = [];
const pathToDest = [];
dfs(node, startValue, pathToStart);
dfs(node, destValue, pathToDest);
return 'U'.repeat(pathToStart.length) + pathToDest.join('');
};
我们可以从
时间复杂度
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def getDirections(
self, root: Optional[TreeNode], startValue: int, destValue: int
) -> str:
def dfs(node: Optional[TreeNode], x: int, path: List[str]):
if node is None:
return False
if node.val == x:
return True
path.append("L")
if dfs(node.left, x, path):
return True
path[-1] = "R"
if dfs(node.right, x, path):
return True
path.pop()
return False
path_to_start = []
path_to_dest = []
dfs(root, startValue, path_to_start)
dfs(root, destValue, path_to_dest)
i = 0
while (
i < len(path_to_start)
and i < len(path_to_dest)
and path_to_start[i] == path_to_dest[i]
):
i += 1
return "U" * (len(path_to_start) - i) + "".join(path_to_dest[i:])
class Solution {
public String getDirections(TreeNode root, int startValue, int destValue) {
StringBuilder pathToStart = new StringBuilder();
StringBuilder pathToDest = new StringBuilder();
dfs(root, startValue, pathToStart);
dfs(root, destValue, pathToDest);
int i = 0;
while (i < pathToStart.length() && i < pathToDest.length()
&& pathToStart.charAt(i) == pathToDest.charAt(i)) {
++i;
}
return "U".repeat(pathToStart.length() - i) + pathToDest.substring(i);
}
private boolean dfs(TreeNode node, int x, StringBuilder path) {
if (node == null) {
return false;
}
if (node.val == x) {
return true;
}
path.append('L');
if (dfs(node.left, x, path)) {
return true;
}
path.setCharAt(path.length() - 1, 'R');
if (dfs(node.right, x, path)) {
return true;
}
path.deleteCharAt(path.length() - 1);
return false;
}
}
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
string getDirections(TreeNode* root, int startValue, int destValue) {
string pathToStart, pathToDest;
dfs(root, startValue, pathToStart);
dfs(root, destValue, pathToDest);
int i = 0;
while (i < pathToStart.size() && i < pathToDest.size() && pathToStart[i] == pathToDest[i]) {
i++;
}
return string(pathToStart.size() - i, 'U') + pathToDest.substr(i);
}
private:
bool dfs(TreeNode* node, int x, string& path) {
if (node == nullptr) {
return false;
}
if (node->val == x) {
return true;
}
path.push_back('L');
if (dfs(node->left, x, path)) {
return true;
}
path.back() = 'R';
if (dfs(node->right, x, path)) {
return true;
}
path.pop_back();
return false;
}
};
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func getDirections(root *TreeNode, startValue int, destValue int) string {
var dfs func(node *TreeNode, x int, path *[]byte) bool
dfs = func(node *TreeNode, x int, path *[]byte) bool {
if node == nil {
return false
}
if node.Val == x {
return true
}
*path = append(*path, 'L')
if dfs(node.Left, x, path) {
return true
}
(*path)[len(*path)-1] = 'R'
if dfs(node.Right, x, path) {
return true
}
*path = (*path)[:len(*path)-1]
return false
}
pathToStart := []byte{}
pathToDest := []byte{}
dfs(root, startValue, &pathToStart)
dfs(root, destValue, &pathToDest)
i := 0
for i < len(pathToStart) && i < len(pathToDest) && pathToStart[i] == pathToDest[i] {
i++
}
return string(bytes.Repeat([]byte{'U'}, len(pathToStart)-i)) + string(pathToDest[i:])
}
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function getDirections(root: TreeNode | null, startValue: number, destValue: number): string {
const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => {
if (node === null) {
return false;
}
if (node.val === x) {
return true;
}
path.push('L');
if (dfs(node.left, x, path)) {
return true;
}
path[path.length - 1] = 'R';
if (dfs(node.right, x, path)) {
return true;
}
path.pop();
return false;
};
const pathToStart: string[] = [];
const pathToDest: string[] = [];
dfs(root, startValue, pathToStart);
dfs(root, destValue, pathToDest);
let i = 0;
while (pathToStart[i] === pathToDest[i]) {
++i;
}
return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join('');
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} startValue
* @param {number} destValue
* @return {string}
*/
var getDirections = function (root, startValue, destValue) {
const dfs = (node, x, path) => {
if (node === null) {
return false;
}
if (node.val === x) {
return true;
}
path.push('L');
if (dfs(node.left, x, path)) {
return true;
}
path[path.length - 1] = 'R';
if (dfs(node.right, x, path)) {
return true;
}
path.pop();
return false;
};
const pathToStart = [];
const pathToDest = [];
dfs(root, startValue, pathToStart);
dfs(root, destValue, pathToDest);
let i = 0;
while (pathToStart[i] === pathToDest[i]) {
++i;
}
return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join('');
};