Given a binary tree
struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; }
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL
.
Initially, all next pointers are set to NULL
.
Note:
For example,
Given the following perfect binary tree,
1 / \ 2 3 / \ / \ 4 5 6 7
After calling your function, the tree should look like:
1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL
分析:
题意给我们一棵“完全二叉树”,让我们把二叉树中每个结点的next域根据如例子那样给它赋值。
看到这个题目,我们的第一反应可能是
1、层次遍历二叉树(这样要用到一个queue队列,并不满足题意的对空间的要求)
2、递归方法(这个是可以的)
但因为这道题目很特殊,二叉树是一棵完全二叉树,所以我们现在要用循环迭代的方法来求解这道题。
具体看代码中的注释
AC代码:
/** * Definition for binary tree with next pointer. * public class TreeLinkNode { * int val; * TreeLinkNode left, right, next; * TreeLinkNode(int x) { val = x; } * } */ public class Solution { public void connect(TreeLinkNode root) { if (root == null) return ; //每一层的最左边的那个结点 TreeLinkNode leftNode = root; while (leftNode != null){ //把同一层的结点用next串起来 TreeLinkNode nowNode = leftNode; while (nowNode != null){ //左孩子的next域指向右孩子 if (nowNode.left != null){ nowNode.left.next = nowNode.right; } //如果一个结点nowNode的右孩子不为空,却这个结点nowNode还有兄弟的话 //那么结点nowNode的右孩子的next域要指向兄弟结点的left域 if (nowNode.right != null && nowNode.next != null){ nowNode.right.next = nowNode.next.left; } //处理结点nowNode的右兄弟(如果为null则不处理) nowNode = nowNode.next; } leftNode = leftNode.left; } } }
Follow up for problem "Populating Next Right Pointers in Each Node".
What if the given tree could be any binary tree? Would your previous solution still work?
Note:
For example,
Given the following binary tree,
1 / \ 2 3 / \ \ 4 5 7
After calling your function, the tree should look like:
1 -> NULL / \ 2 -> 3 -> NULL / \ \ 4-> 5 -> 7 -> NULL
分析:
这题跟上面那个题目的区别在于条件“所给二叉树并不一定是完全二叉树”了,这样子,在上一题的基础上,我们需要去找到每一层的第一个结点,找到这个第一个满足的结点,其他的思路跟上一题是一样的。
AC代码:
/** * Definition for binary tree with next pointer. * public class TreeLinkNode { * int val; * TreeLinkNode left, right, next; * TreeLinkNode(int x) { val = x; } * } */ public class Solution { public void connect(TreeLinkNode root) { if (root == null) return ; //每一层的第一个结点 TreeLinkNode firstNode = root; while (firstNode != null){ TreeLinkNode nowNode = firstNode; //找到第一个不为null的结点. TreeLinkNode tempNode = null; while (nowNode != null){ if (nowNode.left != null){ tempNode = nowNode.left; break; } if (nowNode.right != null){ tempNode = nowNode.right; break; } nowNode = nowNode.next; } //下一层要开始的第一个parent结点 firstNode = tempNode; //把这一层的所有结点用next域串起来 while (nowNode != null){ if (nowNode.left != null && nowNode.left != tempNode){ tempNode.next = nowNode.left; tempNode = nowNode.left; } if (nowNode.right != null && nowNode.right != tempNode){ tempNode.next = nowNode.right; tempNode = nowNode.right; } nowNode = nowNode.next; } } } }
Given numRows, generate the first numRows of Pascal's triangle.
For example, given numRows = 5,
Return
[ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ]
AC代码:
public class Solution { public ArrayList<ArrayList<Integer>> generate(int numRows) { ArrayList<ArrayList<Integer>> arrays = new ArrayList<ArrayList<Integer>>(); for(int i=0; i<numRows; ++i){ ArrayList<Integer> list = new ArrayList<Integer>(); for (int j=0; j<=i; ++j){ if (j == 0 || j == i){ list.add(1); }else{ ArrayList<Integer> temp = arrays.get(i-1); int left = temp.get(j-1); int right = temp.get(j); list.add(left+right); } } arrays.add(list); } return arrays; } }
Given an index k, return the kth row of the Pascal's triangle.
For example, given k = 3,
Return [1,3,3,1]
.
Note:
Could you optimize your algorithm to use only O(k) extra space?
分析:
这道题目和上面那道题目的思路基本上是一样的arrays[i] = arrays[i] + arrays[i-1].但是由于题目要求给我们的空间就O(k),也就是说当我们想改变下一行的值arrays[i]的话我们必须从中间向左边改变,然后右边用r-i 来对称设置值,程序一开始我们先设置出k个位置的值,每个值都为1。
比如 我们要求的K=4 则
r <= k;
r=0: [1,1,1,1,1]
r=1: [1,1,1,1,1];
r=2:[1,2,1,1,1];
r=3:[1,3,3,1,1];
k=4 :[1,4,6,4,1]
大家看看我的代码,如果我们不用 “从中间向左边改变,然后右边用r-i 来对称设置值”这样的话,会出现什么问题!
AC代码:
public class Solution { public ArrayList<Integer> getRow(int rowIndex) { //csdn : http://blog.csdn.net/ljphhj ArrayList<Integer> list = new ArrayList<Integer>(); for (int i=0; i<=rowIndex; ++i){ list.add(1); } for(int i=0; i<=rowIndex; ++i){ //从中间i/2往左移动设置 //避免你从左向中间时,你计算的当前值会影响到下一个位的计算 for (int j=i/2; j>=0; --j){ if (j != 0 && j != i){ int left = list.get(j-1); int right = list.get(j); list.set(j, left+right);//设置值 list.set(i-j, left+right);//对称另一边的值 } } } return list; } }
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
The minimum path sum from top to bottom is 11
(i.e., 2 + 3 + 5 + 1 = 11).
Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.
分析:
这题为典型的DP问题,求最短路径长度,也可以用递归的方法来求.
设用一个数组arr[i][j] 来存储这个三角形。
主要思想:动态规划通常用来求最优解,能用动态规划解决的求最优解问题,必须满足,最优解的每个局部解也都是最优的。以上题为例,最佳路径上面的每个数字到底部的那一段路径,都是从该数字出发到达到底部的最佳路径。
则从三角形的最后一行向上求出每个点对应的最短路径,并把值存下来,最终arr[0][0]就为我们要得到的值
此题目中
最后一行的arr[3][] = {4,1,8,3};
则当到倒数第二行时,每个结点arr[2][i] 的最短路径为 arr[2][i] = min{arr[2][i] + arr[2+1][i] , arr[2][i] + arr[2+1][i+1] };
这样我们就可以得到倒数第二行的所有点到叶子的最短路径长度了,一直往上,直到第一行就得到了最后的结果arr[0][0]
AC代码:
public class Solution { public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) { int len1 = triangle.size(); //从倒数第二行起始 for (int i=len1-2; i>=0; i--){ ArrayList<Integer> listUp = triangle.get(i);//当前行 ArrayList<Integer> listDown = triangle.get(i+1);//当前行的下一行 for (int j=0; j<listUp.size(); ++j){ int left = listDown.get(j); int right = listDown.get(j+1); int min = left > right ? right+listUp.get(j) : left+listUp.get(j); listUp.set(j, min); } } return triangle.get(0).get(0); } }