题解 | 循环右移二叉树

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

/**
 * NC146 循环右移二叉树
 * @author d3y1
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param root TreeNode类
     * @param k int整型
     * @return TreeNode类
     */
    public TreeNode cyclicShiftTree (TreeNode root, int k) {
        return solution(root, k);
    }

    /**
     * 层序遍历
     * @param root
     * @param k
     * @return
     */
    private TreeNode solution(TreeNode root, int k){
        if(root == null){
            return null;
        }

        Queue<QueueNode> queue = new LinkedList<>();
        // level -> count
        HashMap<Integer,Integer> cntMap = new HashMap<>();
        // level+seq -> treeNode
        HashMap<String,TreeNode> treeNodeMap = new HashMap<>();

        // 树的层级 从1开始
        int level = 1;
        // 当前节点 对应父层节点的索引位置 从0开始
        int index = 0;
        // 当前层级 实际节点数目
        int count = 1;
        // 当前层级 实际节点序号(count-1) 从0开始
        int seq = 0;
        queue.offer(new QueueNode(root, level, index, seq));
        cntMap.put(level, count);

        int size,kIdx,upCnt,upSeq,upDirect;
        QueueNode queueNode;
        TreeNode treeNode,upTreeNode;
        while(!queue.isEmpty()){
            size = queue.size();
            level++;
            index = 0;
            count = 0;
            while(size-- > 0){
                queueNode = queue.poll();
                treeNode = queueNode.treeNode;
                // 加入队列
                if(treeNode.left != null){
                    count++;
                    queue.offer(new QueueNode(treeNode.left, level, index, count-1));
                }
                index++;

                if(treeNode.right != null){
                    count++;
                    queue.offer(new QueueNode(treeNode.right, level, index, count-1));
                }
                index++;

                treeNode.left = null;
                treeNode.right = null;
                treeNodeMap.put(queueNode.level+"-"+queueNode.seq, treeNode);

                // 向右循环移动k位
                if(queueNode.level > 1){
                    // 上层(父层) 实际节点数目
                    upCnt = cntMap.get(queueNode.level-1);
                    // 向右循环移动k位 到达的位置索引
                    kIdx = (queueNode.index+k)%(upCnt*2);
                    // 对应的 上层(父层) 节点序号
                    upSeq = kIdx/2;
                    // 判断左右节点
                    upDirect = kIdx%2;
                    // 根据 父层层级+节点序号 找到对应的应该挂载的父节点
                    upTreeNode = treeNodeMap.get((queueNode.level-1)+"-"+upSeq);
                    // 进行挂载
                    if(upDirect == 0){
                        upTreeNode.left = treeNode;
                    }else{
                        upTreeNode.right = treeNode;
                    }
                }
            }
            cntMap.put(level, count);
        }

        return root;
    }

    private class QueueNode{
        TreeNode treeNode;
        int level;
        int index;
        int seq;
        public QueueNode(TreeNode treeNode, int level, int index, int seq){
            this.treeNode = treeNode;
            this.level = level;
            this.index = index;
            this.seq = seq;
        }
    }
}

全部评论

相关推荐

点赞 评论 收藏
分享
建信金科 软件开发岗 16k 双非硕
点赞 评论 收藏
分享
2024-12-26 20:46
复旦大学 C++
国棉17厂丶小王:拿了offer的那个周末晚上去网吧通宵,去网吧不知道玩什么刷了lc的每日一题,然后试着第一次打开了三角洲行动,从此少了一个已经刷了700道题的lc用户,但是烽火地带多了一只🐭🐭
点赞 评论 收藏
分享
只写bug的程序媛:才15,我招行20多万,建设银行50多万,说放弃就放弃
点赞 评论 收藏
分享
01-01 23:38
门头沟学院 Java
杭州同花顺 后端开发 1.5n左右
想当offer收割机的肖恩很爱刷美剧:现在这个环境,狠狠赚钱才是实际的,1是银行的子公司,技术很老,现在银行都在大规模降薪这种科技子公司肯定也在逐渐降薪,而且你也不好跳槽;2虽然钱比1多,但是各种福利待遇基本全无,加班时间可能跟1差不多,但是后续跳槽会比1好;3是大平台,而且钱确实给的很够,发展前景就不用看了,现在这个环境技术发展前景并不一定就好,非技术并不一定就差。个人认为3>2>1
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务