小红有一棵个节点的二叉树,节点的编号为,且每个节点的初始权值都为。
对于这棵二叉树小红会进行次操作,每次操作小红会选择一个节点编号,让以该编号节点为根的子树上节点的权值都异或上。
小红现在给你这棵树的结构以及每次操作的情况,小红想知道在她进行次操作之后该棵二叉树各个节点的权值情况是多少呢,请你返回该树的权值情况。
你需要完善一个函数,函数的第一个参数为给定的树的编号情况,第二个参数代表小红的操作,每个操作的第一项为编号,第二项为异或的值。
{1,2,3},[[2,4],[1,2]]
{2,6,2}
1 权值情况: 0 -> 0 -> 2 / \ / \ / \ / \ 2 3 0 0 4 0 6 2
{2,1,3,#,4},[[3,2],[1,4],[1,3],[4,2],[2,1]]
{1,6,3,#,4}
。
from collections import defaultdict class Solution: def xorTree(self , root: TreeNode, op: List[List[int]]) -> TreeNode: qu = [] op_dict = defaultdict(list) index2nums = defaultdict(int) for i in op: op_dict[i[0]].append(i[1]) qu.append(root) while qu: node = qu.pop(0) index = node.val if node.left!=None: qu.append(node.left) if node.right!=None: qu.append(node.right) if index in op_dict: for i in op_dict[index]: temp = [] temp.append(node) while temp: temp_node = temp.pop(0) index = temp_node.val index2nums[index]= index2nums[index]^i if temp_node.left!=None: temp.append(temp_node.left) if temp_node.right!=None: temp.append(temp_node.right) qu.append(root) while qu: node = qu.pop(0) node.val = index2nums[node.val] if node.left!=None: qu.append(node.left) if node.right!=None: qu.append(node.right) return root
//简单明了 public class Solution { private Map<Integer,TreeNode> map = new HashMap<Integer,TreeNode>(); //先序遍历,将树的id,节点记录下来,并重新赋值0 public void Preorder(TreeNode root){ if (root == null) return ; map.put(root.val,root); root.val = 0; Preorder(root.left); Preorder(root.right); } //异或操作树 public void SetTree(TreeNode root,int v){ if (root == null) return; root.val ^= v; SetTree(root.left,v); SetTree(root.right,v); } public TreeNode xorTree (TreeNode root, ArrayList<ArrayList<Integer>> op) { Preorder(root); for (int i =0; i < op.size(); i++){ SetTree(map.get(op.get(i).get(0)),op.get(i).get(1)); } return root; } }
/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * }; */ class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 返回值的树节点中val表示节点权值 * @param root TreeNode类 给定的初始树节点中的val表示节点编号 * @param op int整型vector<vector<>> op的组成为[[id,v],[id,v],[id,v],...] * @return TreeNode类 */ TreeNode* xorTree(TreeNode* root, vector<vector<int> >& op) { // write code here unordered_map<int, int> m; for(auto& v:op) m[v[0]]^=v[1]; search(root,m, 0); return root; } void search(TreeNode* t,unordered_map<int, int>& m, int n) { if(t==nullptr) return; t->val = m[t->val]; t->val^=n; search(t->left,m,t->val); search(t->right,m,t->val); } };
import java.util.*; public class Solution { public TreeNode xorTree (TreeNode root, ArrayList<ArrayList<Integer>> op) { Map<Integer, Integer> map = new HashMap<>(); for (List<Integer> l : op) { map.put(l.get(0), map.getOrDefault(l.get(0), 0) ^ l.get(1)); } search(root, map, 0); return root; } private static void search(TreeNode root, Map<Integer, Integer> map, int n) { if (root == null) return; root.val = map.getOrDefault(root.val, 0); root.val ^= n; search(root.left, map, root.val); search(root.right, map, root.val); } }
/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * }; */ class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 返回值的树节点中val表示节点权值 * @param root TreeNode类 给定的初始树节点中的val表示节点编号 * @param op int整型vector<vector<>> op的组成为[[id,v],[id,v],[id,v],...] * @return TreeNode类 */ unordered_map<int, TreeNode*> m; // 通过编号映射到树的节点,后面通过编号找树的对应节点的时候会便捷点 // 先序遍历,将树的编号id映射到所对应的节点,用map记录下来这段关系,并将节点的值重新赋值为0,因为题目要求每个节点的权值为0 void Preorder(TreeNode* root) { if(root == nullptr) return; m[root->val] = root; root->val = 0; Preorder(root->left); Preorder(root->right); } // 从根节点开始,把根节点下面的整棵树的节点值都异或一遍 void SetTree(TreeNode* root, int v) { if(root == nullptr) return; root->val ^= v; SetTree(root->left, v); SetTree(root->right, v); } TreeNode* xorTree(TreeNode* root, vector<vector<int> >& op) { Preorder(root); for(int i = 0; i < op.size(); ++i) { auto t = m[op[i][0]]; SetTree(t, op[i][1]); } return root; } //另外一种思路:但是行不通的,看看就行 // for循环:深度优先遍历,在遍历的时候,如果val和op[i][0]相等,就让m[root]^=op[i][1] // 不过这样的话,虽然能够让每个节点的权值都进行异或,但是返回的值不是一棵完整的树(题目要return TreeNode*类型),是一个map,如果还另外去构建一棵树的话,就过于麻烦了 // 也就是说题目暗含的意思就是要你把节点的val改掉,改成0^op[i][1],而不是上面你那个意思。 };
/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * }; */ class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 返回值的树节点中val表示节点权值 * @param root TreeNode类 给定的初始树节点中的val表示节点编号 * @param op int整型vector<vector<>> op的组成为[[id,v],[id,v],[id,v],...] * @return TreeNode类 */ void fzTree(TreeNode* root, unordered_map<int, int> &lay, int val, int id) { if (root -> val == id) { lay[root -> val] ^= val; return; } if(root -> left != NULL) { fzTree(root -> left, lay, val, id); } if(root -> right != NULL) { fzTree(root -> right, lay, val, id); } } void buildTree(TreeNode* root, TreeNode* fhs, unordered_map<int, int> &mii, unordered_map<int, int> &lay) { if(root -> left != NULL) { lay[root -> left -> val] ^= lay[root -> val]; TreeNode* left = (TreeNode*) malloc(sizeof(TreeNode)); left -> left = NULL; left -> right = NULL; left -> val = mii[root -> left -> val] ^ lay[root -> left -> val]; fhs -> left = left ; buildTree(root -> left, fhs -> left, mii, lay); } if(root -> right != NULL) { lay[root -> right -> val] ^= lay[root -> val]; TreeNode* right = (TreeNode*) malloc(sizeof(TreeNode)); right -> left = NULL; right -> right = NULL; right -> val = mii[root -> right -> val] ^ lay[root -> right -> val]; fhs -> right = right ; buildTree(root -> right, fhs -> right, mii, lay); } } TreeNode* xorTree(TreeNode* root, vector<vector<int> >& op) { //无用的mii unordered_map<int, int> mii{}; //树的异或值懒标记 unordered_map<int, int> lay{}; // write code here //懒标记赋值过程 for (auto i : op) { // i[0]是id i[1]是v lay[i[0]] ^= i[1]; } //返回树 TreeNode* fhs = (TreeNode*) malloc(sizeof(TreeNode)); fhs -> val = mii[root -> val] ^ lay[root -> val]; fhs -> left = NULL; fhs -> right = NULL; TreeNode* build = root; buildTree(build, fhs, mii, lay); return fhs; } };
public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 返回值的树节点中val表示节点权值 * @param root TreeNode类 给定的初始树节点中的val表示节点编号 * @param op int整型ArrayList<ArrayList<>> op的组成为[[id,v],[id,v],[id,v],...] * @return TreeNode类 */ public TreeNode xorTree (TreeNode root, ArrayList<ArrayList<Integer>> op) { // write code here int sum = 1; Queue<TreeNode> q = new LinkedList<>(); q.add(root); while(!q.isEmpty()) { TreeNode front = q.poll(); //System.out.println(front.val); if(front.left != null) {q.add(front.left); sum++;} if(front.right != null) {q.add(front.right); sum++;} } int[]&nbs***bsp;= new int[sum + 1]; for(int i = 0; i < op.size(); i++) { int idx = op.get(i).get(0); int val = op.get(i).get(1); or[idx] ^= val; } dfs(root,&nbs***bsp;0); return root; } private void dfs(TreeNode root, int[]&nbs***bsp;int val) { if(root == null) return; root.val = val ^ or[root.val]; if(root.left != null) dfs(root.left,&nbs***bsp;root.val); if(root.right != null) dfs(root.right,&nbs***bsp;root.val); } }
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 返回值的树节点中val表示节点权值 * @param root TreeNode类 给定的初始树节点中的val表示节点编号 * @param op int整型vector<vector<>> op的组成为[[id,v],[id,v],[id,v],...] * @return TreeNode类 */ TreeNode *xorTree(TreeNode *root, vector<vector<int> > &op) { // write code here unordered_map<int, int> mp; for (auto &opi : op) { mp[opi[0]] ^= opi[1]; } dfs(root, mp, 0); return root; } void dfs(TreeNode *root, unordered_map<int, int> &mp, int pre) { if (root == nullptr) return; pre = root->val = mp[root->val] ^ pre; dfs(root->left, mp, pre); dfs(root->right, mp, pre); } };