题解 | #循环右移二叉树#

循环右移二叉树

https://www.nowcoder.com/practice/dd954e299e534af3986a73f98dbdd8a7

解题思路:1.对二叉树进行填充,补全缺失的右子树或者左子树,补充的节点值为-1;
2.对二叉树进行层序遍历,获取每一层的节点。
3.对第二步获取到的节点进行遍历,分别获取父节点和子节点,对子节点进行往右偏移K位获取新的子节点,然后按序赋值给父节点,注意父节点的值如果为-1,是不可以赋值上去的。
4.对二叉树进行递归,去除掉值为-1的节点,得到的最终二叉树就是结果。

ArrayList<ArrayList<TreeNode>> res = new ArrayList<>();
public TreeNode cyclicShiftTree (TreeNode root, int k) {
    // write code here
    if(root==null){
        return null;
    }
    fillTreeNode(root);
    levelOfIterator(root,0);
    for (int i = res.size()-1; i > 0; i--) {
        ArrayList<TreeNode> parents = res.get(i-1);
        TreeNode parent;
        int num =0;
        ArrayList<TreeNode> childrens = res.get(i);
        handleChildren(childrens,k);
        for (TreeNode treeNode : parents) {
            parent = treeNode;
            if (parent.val != -1) {
                parent.left = childrens.get(num);
                num++;
                parent.right = childrens.get(num);
                num++;
            }
        }
    }
    modifyTreeNode(root);
    return root;
}
//去除值为-1的节点
private void modifyTreeNode(TreeNode root) {
    if(root==null){
        return;
    }
    if(root.left!=null&&root.left.val==-1){
        root.left=null;
    }
    if(root.right!=null&&root.right.val==-1){
        root.right=null;
    }
    modifyTreeNode(root.left);
    modifyTreeNode(root.right);
}
//调整子节点的顺序,往右偏移K个位置
private void handleChildren(ArrayList<TreeNode> children, int k) {
    k=k% children.size();
    TreeNode last ;
    while (k>0){
        last = children.get(children.size()-1);
        for (int i = children.size()-1; i > 0; i--) {
            children.set(i, children.get(i-1));
        }
        children.set(0,last);
        k--;
    }
}
//层序遍历
private void levelOfIterator(TreeNode root,int level) {
    if(level==res.size()){
        res.add(new ArrayList<>());
    }
    ArrayList<TreeNode> treeNodeArrayList = res.get(level);
    treeNodeArrayList.add(root);
    if(root.left!=null){
        levelOfIterator(root.left,level+1);
    }
    if(root.right!=null){
        levelOfIterator(root.right,level+1);
    }
}
//填充二叉树,填充节点的值为-1
private void fillTreeNode(TreeNode root) {
    if(root==null||root.val==-1){
        return;
    }
    if(root.left == null){
        root.left=new TreeNode(-1);
    }
    if(root.right == null){
        root.right=new TreeNode(-1);
    }
    fillTreeNode(root.left);
    fillTreeNode(root.right);
}
#二叉树#
全部评论

相关推荐

02-07 12:06
已编辑
华侨大学 测试开发
最近看到很多&nbsp;92&nbsp;的,甚至是硕士,开始往测开赛道卷,说实话有点看不懂。先把话说清楚,大厂里的测开,绝大多数时间干的还是测试的活,只是写点自动化脚本、维护测试平台、接接流水线,真正像开发一样做系统、做架构、做核心平台的测开少得可怜,基本都集中在核心提效组,而且人很少,外面进去的大概率轮不到你,我想真正干过人都清楚。很多人被洗脑了,以为测开也是开,和后端差不多,只是更简单、更轻松、还高薪。现实情况是,测开和开发的职业路径完全不一样。开发的核心是业务和系统能力,测开的核心是稳定性和覆盖率,前者是往上走,后者天花板非常明显。你可以见到很多开发转测开,但你很少见到干了几年测开还能顺利转回开发的。更现实一点说,92&nbsp;的高学历如果拿来做测开,大部分时间就是在做重复性很强的杂活,这种工作对个人能力的放大效应非常弱。三年下来,你和一个双非的,甚至本科的测开差距不会太大,但你和同龄的后端、平台开发差距会非常明显。这不是努不努力的问题,是赛道问题。所谓测开简单高薪,本质上是把极少数核心测开的上限,当成了整个岗位的常态来宣传。那些工资高、技术强的测开,本身就是开发水平,只是挂了个测开的名。普通人进去,99%&nbsp;做的都是项目兜底型工作,而不是你想象中的平台开发。测开不是不能做,但它绝对不是开发的平替,也不是性价比最优解。如果你是真的不想做开发,追求稳定,那测开没问题。但如果你只是觉得测开比后端容易,还能进大厂,那我劝你冷静一点,这只是在用短期安全感换长期天花板。有92的学历,如果你连测开这些重复性工作都能心甘情愿接受,那你把时间精力用在真正的开发、系统、业务深度上,回报大概率比卷测开要高得多。想清楚再下场,别被岗位名和话术带偏了,就算去个前端客户端也是随便占坑的,测开是一个坑位很少赛道,反而大面积学历下放,不用想也能知道会是什么结果,我想各位在JAVA那里已经看到了
小浪_Coding:工作只是谋生的手段 而不是相互比较和歧视
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务