右移动二叉树
题目
现给定一个二叉树root,要求把二叉树每层的节点向右移k位,最后返回一个右移之后的二叉树
思路
层序遍历二叉树,获取二叉树每层的所有结点的值,并且右移。然后再对每层的节点重新赋值
Collections.rotate
是 Java 中 java.util.Collections
提供的一个静态方法,用于旋转列表中的元素位置。其作用是将列表中的元素按照指定的距离进行旋转,右移或左移,具体行为取决于输入的旋转距离 kkk 的正负值。
代码
public TreeNode shiftTree(TreeNode root, int k) {
if(root == null) return null;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();
List<TreeNode> list = new ArrayList<TreeNode>();
for(int i=0;i<size;i++){
TreeNode node = queue.poll();
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
list.add(node);
}
List<Integer> shifted = new ArrayList<>();
for(TreeNode value:list){
shifted.add(value.val);
}
int t = k%shifted.size();
Collections.rotate(shifted, t);
for(int i=0;i<shifted.size();i++){
list.get(i).val = shifted.get(i);
}
}
return root;
}
public void printTree(TreeNode root) {
if (root == null) {
System.out.println("Tree is empty.");
return;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if (node != null) {
System.out.print(node.val + " ");
queue.offer(node.left);
queue.offer(node.right);
} else {
System.out.print("null ");
}
}
System.out.println();
}
}
public static void main(String[] args) {
BinaryTreeShift solution = new BinaryTreeShift();
// 构造示例二叉树
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(7);
System.out.println("原始二叉树:");
solution.printTree(root);
// 右移每层节点
int k = 2;
TreeNode shiftedRoot = solution.shiftTree(root, k);
System.out.println("右移后的二叉树:");
solution.printTree(shiftedRoot);
}
戳气球
题目
思路
- 将问题拆分为子问题:
- 例如,计算从第 i 到第 j 的气球之间的最大硬币数。
- 假设最后戳破的是第 k 个气球,则问题可以拆分为:
- 左半部分:[i, k-1]
- 右半部分:[k+1, j]
- 合并结果:最后一次戳破 k 的硬币值 + 左右部分的结果。
- 动态规划的定义:
- 定义 dp[i][j] 为戳破区间 [i, j] 内气球所能获得的最大硬币数。
- 状态转移方程:
- 如果最后戳破的气球是 k,则:
-
dp[i][j] = Math.max(dp[i][j],dp[i][k-1]+dp[k+1][j]+newInt[i-1]*newInt[k]*newInt[j+1]);
三层循环详解
首先第一层循环,表示当前正在计算的区间长度
for(int size = 1;size<=nums.length;size++)
第二层循环 ,表示当前区间起点
for(int i=1;i<= nums.length-size+1;i++)
int j = i + length - 1; // 区间终点
第三层循环就是最后戳破的气球
for(int k=i;k<=j;k++)
代码
public int maxCoins(int[] nums) {
int[][] dp = new int[nums.length+2][nums.length+2];
int[] newInt = new int[nums.length+2];
newInt[0] = 1;
newInt[nums.length+1]=1;
System.arraycopy(nums, 0, newInt, 1, nums.length);
for(int size = 1;size<=nums.length;size++){
for(int i=1;i<= nums.length-size+1;i++){
int j = i+size-1;
for(int k=i;k<=j;k++){
dp[i][j] = Math.max(dp[i][j],dp[i][k-1]+dp[k+1][j]+newInt[i-1]*newInt[k]*newInt[j+1]);
}
}
}
return dp[1][nums.length];
}
总结
更难了,今天下班吃兔子犒劳一下自己